Author Topic: implementing speed in projectiles with libtcod  (Read 23226 times)

flammanj

  • Newcomer
  • Posts: 3
  • Karma: +0/-0
    • View Profile
    • Email
implementing speed in projectiles with libtcod
« on: July 23, 2012, 10:40:08 AM »
Hi to all, I am new to this forum and new to the development of RL. Aside from some bits of php, I am a complete newcomer to programming.

I started writing a RL with Python and libtcod, using this totally awesome tutorial on roguebasin:
http://roguebasin.roguelikedevelopment.org/index.php/Complete_Roguelike_Tutorial,_using_python%2Blibtcod

I finished it, understanding quite everything and learning the basics of the language quite fast. Now I stepped out, and wanted to go working towards some own RLs, each becoming more complex.

My first one should be some kind of Sci-Fi-Survival (a bit into the direction of Unreal World). However, I need to implement different things, one after another. To some of you, this may be not too hard, using all the experience you have about general programming. To me, this is a completely new world. I know the theory about game design and similiar stuff, but programming is very new to me.

My first problem is the following:

I spent hours of searching the web and reading existing code to finally write a Projectile system, inside a sandbox I created just for testing such things. I used libtcod's line_step() method.
However, I want to add some kind of speed feature, something that says how fast my projectiles travel.
I understand that I need to multiply some coordinates with a speed factor.
However, my logic fails and I just can't think of where to put this speed factor (maybe I am just too tired).

Could any of you please read through my Projectile class and tell me where to put the speed?
In case you need to know: the game runs in real-time, with 20fps
the prints are just for control, it took me hours to get the drawing of the Projectiles the right way

I am also open for anything else you can see in my code (maybe something that will cause errors at a later point?)

Code: [Select]
class Projectile(Object):

    def __init__(self, x, y, start_x, start_y, end_x, end_y, char, speed, color=libtcod.red):
        self.x = x
        self.y = y
        self.start_x = start_x
        self.start_y = start_y
        self.end_x = end_x
        self.end_y = end_y
        self.speed = speed
        self.color = color
        self.char = char

        libtcod.line_init(start_x, start_y, end_x, end_y)

    def proj_draw(self):
        libtcod.console_set_foreground_color(con, libtcod.red)
        libtcod.console_put_char(con, self.current_x, self.current_y, '*', libtcod.BKGND_NONE)
        projectiles.append(self)
        render_all()
        print('projectile drawn')
        libtcod.console_flush()

    def proj_clear(self, x, y):
        libtcod.console_put_char(con,x,y, ' ', libtcod.BKGND_NONE)

    def proj_step(self):
        #follow line in steps
        self.current_x, self.current_y = libtcod.line_step()
               
        self.proj_draw()
       
        if self.current_x == None or self.current_y == None:
            print('dungalung... hits the floor..')
            return None, None

         #check objects on the way
        if is_blocked(self.current_x, self.current_y):
            print('katsching! the projectile hits')
            return None, None
           

        #out of map - ignore
        #elif map_out(self.current_x, self.current_y):
         #   print('The projectile is gone forever')
          #  return None, None



        return self.current_x, self.current_y

    def proj_shoot(self):
        x, y = self.proj_step()
        ox, oy = self.current_x, self.current_y
        while(not x is None and not y is None):
            print ('duringshot')
            ox, oy = x, y
            x, y = self.proj_step()
            self.proj_clear(ox, oy)
            self.proj_clear(x, y)
        print ('aftershot')
        self.proj_clear(ox, oy)

kraflab

  • Rogueliker
  • ***
  • Posts: 454
  • Karma: +0/-0
    • View Profile
    • kraflab.com
Re: implementing speed in projectiles with libtcod
« Reply #1 on: July 23, 2012, 11:44:35 AM »
I know the theory about game design and similiar stuff...

Merely by writing this line has the line been proven false.

Libtcod is poop, so I'm afraid I can't help you.

Darren Grey

  • Rogueliker
  • ***
  • Posts: 2027
  • Karma: +0/-0
  • It is pitch black. You are likely to eat someone.
    • View Profile
    • Games of Grey
Re: implementing speed in projectiles with libtcod
« Reply #2 on: July 23, 2012, 12:06:01 PM »
Wow, that's really helpful and informative, kraflab, and a great way to welcome someone to the community.

I can't help you much, flammanj, but I'm sure someone with some libtcod experience can chime in.  Otherwise you can usually get useful advice over at rec.games.roguelike.development.

flammanj

  • Newcomer
  • Posts: 3
  • Karma: +0/-0
    • View Profile
    • Email
Re: implementing speed in projectiles with libtcod
« Reply #3 on: July 23, 2012, 12:54:45 PM »
@kraflab

I want to make sense of whatever you write, even if you probably are just trolling...
I do not even ask what you mean by the first line. I don't understand what you imply with this and you probably haven't understood what I mean.

Concerning libtcod:
why do you consider it "poop"? Do you prefer writing everything by yourself? Are there better alternatives for "noob" programmers?
I mean, I first wasn't sure about it at first, but it seems to have a solution for most problems I could imagine when it comes to start writing a RL. My first thoughts were: how do you write field of view? how do you start making projectiles etc ? Libtcod was the only solution I found out there, plus I think it is easy to replace libtcod functions with own functions as soon as programming skills grow.
I have no idea what other people think of libtcod and why.
I would always be glad to learn of other alternatives.

Darren Grey

  • Rogueliker
  • ***
  • Posts: 2027
  • Karma: +0/-0
  • It is pitch black. You are likely to eat someone.
    • View Profile
    • Games of Grey
Re: implementing speed in projectiles with libtcod
« Reply #4 on: July 23, 2012, 12:59:59 PM »
Libtcod is well-known in the RL community as a very useful tool, and a lot of great games (especially 7DRLs) have been made using it.  Check out PrincessRL, Vicious Orcs and Smart Kobold as some examples of how to do a libtcod game well.

kraflab

  • Rogueliker
  • ***
  • Posts: 454
  • Karma: +0/-0
    • View Profile
    • kraflab.com
Re: implementing speed in projectiles with libtcod
« Reply #5 on: July 23, 2012, 06:33:47 PM »
Sorry I was a bit tired when I wrote that otherwise I may have helped you out.

Anyway yes I do prefer to write everything myself, but I also hear more and more bad things about libtcod in general and nothing good.  Personally it seems a lot faster (and more informative) to me to write something from scratch as opposed to figuring out how someone else's engine does that thing.  Of course the first step is to pick a programming language that isn't so far back in the stone age that it can't do cross platform graphics natively (not that this applies to you, since I don't really know your language).  I am also against game development tutorials in general (for the same reason) and I think anyone who even mentions the phrase "theory of game design" legitimately should probably erase their memories and start from scratch.  So ya, your post kind of annoyed me in multiple ways so I couldn't hold myself back in that regard.

Here's a specific example of a bad thing about libtcod: I don't know what its functions do and thus cannot help you :)

XLambda

  • Rogueliker
  • ***
  • Posts: 208
  • Karma: +0/-0
    • MSN Messenger - tau_iota@live.de
    • View Profile
    • The Weird Rogue
Re: implementing speed in projectiles with libtcod
« Reply #6 on: July 23, 2012, 08:41:42 PM »
Personally it seems a lot faster (and more informative) to me to write something from scratch as opposed to figuring out how someone else's engine does that thing.

You're probably right about it being informative, but faster? I disagree strongly. It's a ton of work. A powerful and fast displaying solution is (please excuse my language) damn hard to come by. You can trust me on that one. I'm porting most of the libtcod toolkits and interfaces over to java, and I'm just amazed how much work jice has put into them. Also, his C is far better than mine.
To write something much smaller than libtcod, say in C++, you already have to figure out either SDL or openGL. Same with Java - you have to figure out AWT and/or swing to get even the simplest display engine running. With Python you probably want to get something through ctypes - so you're stuck with figuring out both ctypes AND your native lib. And I'd say that most of these are much harder to figure out than the very pleasant interfaces of libtcod and others.

requerent

  • Rogueliker
  • ***
  • Posts: 355
  • Karma: +0/-0
    • View Profile
Re: implementing speed in projectiles with libtcod
« Reply #7 on: July 23, 2012, 09:58:39 PM »
Quote
I spent hours of searching the web and reading existing code to finally write a Projectile system, inside a sandbox I created just for testing such things. I used libtcod's line_step() method.
However, I want to add some kind of speed feature, something that says how fast my projectiles travel.
I understand that I need to multiply some coordinates with a speed factor.
However, my logic fails and I just can't think of where to put this speed factor (maybe I am just too tired).

Velocity is the word that describes what you're trying to achieve.


I'm not familiar with libtcod or python- but I assume linestep will move one tile along a line.

This, however, is what we're looking at.
Code: [Select]
def proj_step(self):
        #follow line in steps
        self.current_x, self.current_y = libtcod.line_step()
               
        self.proj_draw()
       
        if self.current_x == None or self.current_y == None:
            print('dungalung... hits the floor..')
            return None, None

         #check objects on the way
        if is_blocked(self.current_x, self.current_y):
            print('katsching! the projectile hits')
            return None, None
           

        #out of map - ignore
        #elif map_out(self.current_x, self.current_y):
         #   print('The projectile is gone forever')
          #  return None, None



        return self.current_x, self.current_y


Let's start with an unrealistic representation of speed in tiles per turn. That is, every turn, such and such projectile moves X amount of tiles.

1)
The simplest non-ideal way to resolve this is to add a tilesPerTurn variable to your projectile class. Make a new function that calls proj_step in a loop that runs a number of times equal to tilesPerTurn. Whenever the projectile is created, set its tilesPerTurn to whatever you want-- this is, in effect, its speed.


This will be the simplest way to resolve your issue, but it isn't logically balanced in the sense that two projectiles moving at the same time won't move in a realistic way (one will travel its turns worth of movement before the other, instead of both going at the same time).

I don't recommend this for a real time game, but any other solution will either require more knowledge of libctod OR implementing interpolation. Libctod might automagically take care of some of this stuff for you, but if it doesn't and you don't want to do anything that involves any rewrites elsewhere, you could do the above.




Interpolation, if you're not familiar, is a way to tween objects between two points in a way that reacts with the game world realistically. Suppose you have two bullets in 2d moving toward one another at a perpendicular angle. They WILL cross one another's paths, but how will you know if they collide or not? There are many algorithms that will do a lot of the work for you, but if you're new to programming I wouldn't recommend it.

The whole value of turn-based tiled games is that collision and interpolation is very very easy- I'd recommend dropping the real-time aspect and master turn-based logic first instead.

kraflab

  • Rogueliker
  • ***
  • Posts: 454
  • Karma: +0/-0
    • View Profile
    • kraflab.com
Re: implementing speed in projectiles with libtcod
« Reply #8 on: July 24, 2012, 08:42:49 AM »
Personally it seems a lot faster (and more informative) to me to write something from scratch as opposed to figuring out how someone else's engine does that thing.

You're probably right about it being informative, but faster? I disagree strongly. It's a ton of work. A powerful and fast displaying solution is (please excuse my language) damn hard to come by. You can trust me on that one. I'm porting most of the libtcod toolkits and interfaces over to java, and I'm just amazed how much work jice has put into them. Also, his C is far better than mine.
To write something much smaller than libtcod, say in C++, you already have to figure out either SDL or openGL. Same with Java - you have to figure out AWT and/or swing to get even the simplest display engine running. With Python you probably want to get something through ctypes - so you're stuck with figuring out both ctypes AND your native lib. And I'd say that most of these are much harder to figure out than the very pleasant interfaces of libtcod and others.

Sorry, but powerful and fast displaying is trivial if you use, as I mentioned in my post, a language that isn't still in the stone age :P That's just my experience.  I wrote my ascii display engine literally in a day and was using it to display tile quantities much larger than anything in a typical roguelike and run things faster than in a typical roguelike.  Now I don't know all the features of libtcod, but I can't think of anything that took me any time to write and didn't run incredibly fast.  Maybe I'm just good at programming, but as I said I think it just isn't that hard.

Darren Grey

  • Rogueliker
  • ***
  • Posts: 2027
  • Karma: +0/-0
  • It is pitch black. You are likely to eat someone.
    • View Profile
    • Games of Grey
Re: implementing speed in projectiles with libtcod
« Reply #9 on: July 24, 2012, 11:45:46 AM »
Being someone that started from scratch and reinvented the wheel many times, and then moved on to use an existing roguelike engine, I can say there are huge benefits and time-saving features to re-using someone else's code.  And there are a lot of things I've done with the T-Engine that I could never have achieved with my amateur coding skills.  There were benefits to starting from scratch too though (just in terms of learning to code, and having fun, and having better innate knowledge of how the code works) but in general I'd recommend new game developers to start with something like libtcod.

Of course it very much depends on one's own coding skills and preferences.  If we all made games the same way it would be a very boring world...

Z

  • Rogueliker
  • ***
  • Posts: 905
  • Karma: +0/-0
    • View Profile
    • Z's Roguelike Stuff
Re: implementing speed in projectiles with libtcod
« Reply #10 on: July 30, 2012, 02:26:45 AM »
There are big differences in programming talent, some people say that a good programmer is 10 times faster than a typical professional one. What is easy for one is extremely hard for another. So hard to find a general rule.

I also hear more and more bad things about libtcod in general and nothing good.
I don't see many complaints against libtcod. The only thing I personally don't like about it is that it does not natively work with ssh (and other tools).

Libtcod is a library that has two uses: interface (display + keyboard), and auxiliary functions for roguelikes (lines, FOV, etc). For me, it is very easy to create a simple linetracking or FOV, easier than to interact with someone else's library (but if you cannot figure this out yourself, then yeah, go for it). As for the interface, you are not going to interact with the hardware/terminal/whatever directly, that makes no sense. You have to use something. SDL has an advantage that it is a well known library and is easy to set up. Free Pascal has a nice CRT library for ASCII interfaces (as far as I know, and I actually think that Darren Grey's old FP roguelikes looked much better than his new T-engine ones), while Curses has many problems which are solved by Libtcod. My new Noteye library has some advantages over Libtcod, and for new ASCII roguelikes I would use it (of course). By using something non-standard you lose compatibility with some tools (ssh works with Curses/CRT, NotEye also works with libtcod and can produce Curses output for ssh).

Quote
I am also against game development tutorials in general
The one RL dev tutorial that I looked at was indeed bad. If you cannot figure out how to make a @ moving on screen yourself, you should base your work on some game where this already works (popular choices include T-Engine, Angband, Thomas Biskup's Qhack, etc), instead of copying the tutorial.

Quote
and I think anyone who even mentions the phrase "theory of game design" legitimately should probably erase their memories and start from scratch.
Could you elaborate on that?


kraflab

  • Rogueliker
  • ***
  • Posts: 454
  • Karma: +0/-0
    • View Profile
    • kraflab.com
Re: implementing speed in projectiles with libtcod
« Reply #11 on: July 30, 2012, 03:17:50 AM »
Quote
and I think anyone who even mentions the phrase "theory of game design" legitimately should probably erase their memories and start from scratch.
Could you elaborate on that?

There are a lot of people out there that think reading a tutorial or taking a class on theory somehow makes them capable game designers.  Obviously, some people are capable designers from the start, but going in thinking there is some magic formula for success or that there is a proper way of doing things is just terrible in my opinion.  It drives me nuts when someone tells someone the "right" way of coding something or the proper setup for some implementation.  It's much better to think freely and even ignore the procedures of the past (successful or otherwise) in order to keep things moving.

Of course, this is just my view based on my own experience.  It's very easy for me to get things done from a bare-bones starting point because I am very comfortable with coding and design.

Darren Grey

  • Rogueliker
  • ***
  • Posts: 2027
  • Karma: +0/-0
  • It is pitch black. You are likely to eat someone.
    • View Profile
    • Games of Grey
Re: implementing speed in projectiles with libtcod
« Reply #12 on: July 30, 2012, 12:20:31 PM »
At the same time there are a lot of people who never even think of design and simply copy what's been done before.  A big part of articles on game design is to question what has been done both well and badly before.  Essentially they're food for thought, which can help a lot with the "thinking freely" you refer to.

Darren Grey

  • Rogueliker
  • ***
  • Posts: 2027
  • Karma: +0/-0
  • It is pitch black. You are likely to eat someone.
    • View Profile
    • Games of Grey
Re: implementing speed in projectiles with libtcod
« Reply #13 on: July 30, 2012, 02:51:40 PM »
As for the interface, you are not going to interact with the hardware/terminal/whatever directly, that makes no sense. You have to use something. SDL has an advantage that it is a well known library and is easy to set up. Free Pascal has a nice CRT library for ASCII interfaces (as far as I know, and I actually think that Darren Grey's old FP roguelikes looked much better than his new T-engine ones), while Curses has many problems which are solved by Libtcod.

I could make my T-Engine games look *exactly* like my FreePascal games if I wanted to.  The advantage of using someone else's SDL engine is that it gives me a huge amount of extra design freedom for very little extra learning, and certainly a lot less effort than trying to make my own display engine.  Having tried out both methods of operation I can't imagine going back to self-coding everything.  Such a lot of hard work.

Alex E

  • Rogueliker
  • ***
  • Posts: 118
  • Karma: +0/-0
    • View Profile
    • Email
Re: implementing speed in projectiles with libtcod
« Reply #14 on: July 31, 2012, 06:40:24 AM »
In the beginning of every roguelike, you usually have to re-create the same systems you had that most (not all) roguelikes generally have (Ex: Displaying tiles, picking up items).

After making my second roguelike and starting my third, I didn't really want to re-re-create things such as "displaying tiles on a world" or "picking up items", so I  took a lot of the code I created for my second roguelike and put it into my third. Off of that framework, I could make new things I hadn't before.