Page 1 of 1

Turn Based Games

Posted: Sat Jan 24, 2009 10:05 am
by Hrothgar
Just for fun I'm working on a turn based tactical rpg sort of thing in Freebasic.

I'm having trouble coming up with a good way to determine which character gets the next turn. At the moment it just cycles through the characters one by one but ideally I'd like to have it based on each character's speed stat. Does anyone here know a good algorithm for this sort of thing?

I have the characters stored as Type objects so for example if I had 5 characters.

char(1) to char(5)

when it's char(1)'s turn
turn = 1

so when a turn specific event happens (like telling him to move or attack or something)

char(turn).action = move or attack or something

every turn the turn variable would just cycle through 1 to 5

but I'd rather it was based on the char(number).SPEED variable. So that the character with the highest speed would go first and then it would sort out the turns respectively.

I'm already a good 800 lines into this thing so I'd rather not have to change too much.

Thanks for all your help.

Posted: Sat Jan 24, 2009 2:34 pm
by T'lon Nanaki
I'm assuming that your using a for loop to go through the list of characters.

something like:
for i = 0 to 4
char(i).dostuff 'what ever your code is?
next

instead do a nested for loop inside and have it look for characters speed stat
for i = 0 to 4
for i2= 0 to 4
if char(i2).speed = i then
'your turn here
end if
next
next

of course this example assumes that the speed variable is an integer

Posted: Sun Jan 25, 2009 12:48 am
by Hrothgar
Thanks T'lon
Yes I am using a for loop to go through the characters and the speed variable is an integer.

I was thinking of doing something like that with a nested for loop. It works quite well. The bit that troubles me is what happens when two characters have equal speed? I could have it randomly choose between them I guess but then what if there were three characters with equal speed or all of them? would there be a better way?

I think I would rather have it choose turns based on the value of the speed stat relative to the other characters speed stats. For example

if char(1).speed = 3 and char(2).speed = 6 and char(3).speed = 5 then
char(2) would get about twice as many turns as char(1) and char(3) would get more turns than char(1) but less than char(2)

Posted: Mon Jan 26, 2009 11:50 am
by T'lon Nanaki
I just call as I see it, glad I could give some insight :D
out of curiosity is your game gonna be something like the old shining force games or final fantasy tactics, if so I'd love to get a chance to check it out when It's done.

Posted: Sat Mar 28, 2009 7:18 am
by Hrothgar
Yeah that's the sort of thing, It's like an amaturish final fantasy tactics with sprites and an inventory system, magic, items, stats and stuff. My goal is 10 linear levels with scripted events and ai, broken up by a sort of visual novel kind of story system where you can change your equiptment and maybe at certain points acess a shop.

I'm maybe about halfway through the engine. I've got an item system with an inventory, weapons and armor, usable items and quest items, an events system that reads events from a script and acts accordingly, an action system that treats actions of characters like events that can be triggered by either user input (clicking attack etc.) or through the scripted events system, the story engine is coming along, theres some appalling ai (bad guys have no collision detection yet and also sometimes attack empty space), theres damage calculation based on the weapon and strength of the character minus a value for armor, still need to add some magic, I never got around to deciding what to do about the turn thing and it needs a whole lot of stuff to make the interface look and feel better. It's the most ambitious attempt at programming I've undertaken and my code is probably pretty crap but so far so good.

Right now something is annoying me. I'm trying to use a LINE to make some little health bars for my characters but it wont do any alpha blending on it. Without it they look ugly and blocky. I don't understand why this doesn't seem to work.

Code: Select all

line (0,0) - (127*(Char(1).hp/Char(1).maxhp), 63),Rgba(0,255,0,100),bf
shouldn't this make a healthbar for character 1 with an alpha transparency of 100? why is it just solid green?

Posted: Sun Mar 29, 2009 3:25 am
by T'lon Nanaki
I think i have a solution for "who goes first" problem
leave it as is!
in a tactical RPG each "turn" is in fact a predeturmined length of time, wether it's a second or a millenia, so if two characters have the same values just means that they are moving at the same time in "Battle Time"
so a need to choose who would go first in "real time" is irrelevent.
If you pay close attention to both final fantasy tactics and shining force you can actually see that this ideology(wether it's really part of the game's engine or not) is present in both games.

now it only took me a couple of seconds to guess why you can't get your green health bar transparent

take a close look at this code

Code: Select all

Screen 19,32,,1
'screenres 800,600,32,,1

Line(0,100)-(800,120),RGBA(0,0,255,128),bf
line(200,100)-(600,120),rgba(128,0,0,128),bf
Sleep
cls
Screen 19,32,,&h41
'screenres 800,600,32,,&h41

Line(0,100)-(800,120),RGBA(0,0,255,128),bf
line(200,100)-(600,120),rgba(128,0,0,128),bf
Sleep
in the screen and screenres functions threre is a flag value that changes
how the screen acts. for the example above that's why the first time you get a solid red bar and the second time is a purple bar

if you use &h40 with any other flags you will activate the GFX_ALPHA_PRIMITIVES flag and that willl allow alpha blending
chances are you have just &H01 (1) which inorder for alpha channel to be used should be &H41 (that is alpha and fullscreen) :)
let me know if this helped...

Posted: Sun Mar 29, 2009 8:55 am
by Hrothgar
now it only took me a couple of seconds to guess why you can't get your green health bar transparent

Thank you VERY much, that worked perfectly. I'll keep you posted on my progress.

Posted: Sun Mar 29, 2009 11:08 pm
by Ryan
Total non sequitur, but I couldn't resist... re-reading Eragon so I can get to Brisingr and just got past the introduction to Hrothgar toward the end of the book. ;)

Good luck with the game!

Posted: Tue Mar 31, 2009 6:08 am
by Hrothgar
Actually the name comes from Beowulf and norse mythology. Hrothgar was a scandanavian king who's people were under attack by the monster Grendel. Beowulf showed up, killed the monster and saved the day. That book series looks pretty cool though, I'll have to read it some time.

I'm having a little trouble with the ai.

the behaivior of each of the ai characters is written in a script (.txt file) and read by the main program. It's split up into one off ai actions that take up a turn (eg. attack the square in front of you on your xth turn), one off actions that dont take up a turn (eg. shout "GYAARGH i'll kill you!" or something), and normal recurring behaivior (eg. move towards the closest valid target and attack when theres not a one off behavior specified). All this works pretty well at the moment.

I have a subroutine set up that can target the nearest or farthest character from someone as well as whether or not a character is adjacent to them. The bit I'm getting stuck on is the actual movement part.

when a character is moved it is given a char().newx and char().newy and then the movement sub is called that sorts out the animations and plots the path to the new coordinates.

Each character is only allowed to move half the number of tiles as their speed value so if char().speed = 4 then they can move 2 spaces in any direction.

2 characters cannot occupy the same tile.

so the move and attack recurring behavior has to make
char(ai).newx, char(ai).newy
be int(char(ai).speed / 2) tiles towards
char(target).x, char(target).y

unless
char(ai).newx, char(ai).newy = Char(for...next).x, Char(for...next).y
in which case it has to find another newx,newy (collision detection)
or
char(target).x, char(target).y is < int(char(ai).speed / 2) tiles away
in which case it moves to be adjacent

if adjacent = 1 then char(ai) attacks.

any good ideas on the best way to accomplish that?

Posted: Tue Mar 31, 2009 10:19 pm
by T'lon Nanaki
programing AI isn't something that ive never really been able to do to well, sorry can't help U there :(

Posted: Thu Apr 23, 2009 1:10 pm
by T'lon Nanaki
Hrothgar! I was wondering what kind of graphic routines you were using for your game? is it just a simple PUT sequence or did you write some codes or what-not?

Posted: Sun Apr 26, 2009 4:10 am
by Hrothgar
Yeah at the moment it's just bitmaps bloaded into fb.image ptrs and PUT onto the screen. If theres a more effective way of doing things that I don't know about I'd be interested to learn.

Posted: Mon Apr 27, 2009 7:51 pm
by T'lon Nanaki
I asked cause I wrote an entire routine for graphics that I wanted someone to try out and give feed-back on it (I like having people say im good at something every once in a while :) )

the entire thing is in a UDT and it loads multiple bitmaps, has a cropping feature, and can do transparancies.

if your intrested i could send a zip file to your email or what-ever
but i still need a little while (a week at most) to finish some of the functions and fine tune some aspects of the code

Posted: Wed Apr 29, 2009 1:59 am
by Hrothgar
Sure, sounds good. Whenever it's done go ahead and send it to hrothcode at gmail dot com and i'll check it out.

how does it work? I guess it's an oop thing? Does it only load bitmaps or could it do other file formats as well?

Posted: Thu Apr 30, 2009 1:20 am
by T'lon Nanaki
yes it uses OOP on bmp files only ( I havn't learnt how to do other formats yet, there on my list of things to figure out)

it uses a string to id individual bitmaps and you call it's sub\functions

there are a total of 6 subs and 2 functions

I'll include an example code to better explain it

Posted: Thu Apr 30, 2009 3:23 am
by Hrothgar
Sounds good. I'd still be able to use it within other types right? eg. if the bitmap for the first frame of a 10 frame character animation was stored in Char(character).animation(1) would I do something like.

Code: Select all

Type character
        _name as string
        blahblahetc. as integer
        animation(10) as (T'lon'sgfxroutine.image)
end type

dim Char(charno) as character

T'lon'sgfxroutine.load("gfx\animation1.bmp", char(1).animation(1)) 'or whatever the syntax is

on an entirely unrelated note.
Do you know how to get put #fileno to write to the next line of an external file?

according to fbwiki the syntax is
Put #filenum As Integer, [position As longint], data As String
but [position] is the number of characters along that it starts writing not the number of lines down. Is there a way to get it to write a carriage return or something?

I'm using it to record the character's stats to a text file that can be loaded later as a script. Each stat is recorded on a different line of the script with a command in front of it telling what stat to set and a number indicating which character to set it to. Useful for leveling up or saving a game.

Posted: Thu Apr 30, 2009 11:28 am
by T'lon Nanaki
yes you should be able to use it with other types
i havn't tryed doing animations withit but i think if you have your frames
setup in a singe bitmap the cropping funciton can help you keep track of what frame is displayed

as for that example it's pretty damn close
more like:
dim gfx as mygfx <this is why it'll work in other types

mygfx.load "id name","idfile.bmp"

I've realized that there isn't to many bugs in it and should be finished by
tomarow or the next day I'll try write the example to do an animation :)

as for the other i don't think im understanding the question fully, but please wait till after i've sent you my graphics routine (I can only foucus on one or two things at the same time (DAMN ADHD!))

Posted: Wed May 06, 2009 3:16 am
by Hrothgar
Thanks for the gfx routine, It's awesome. I really like the cropping feature and being able to just call the destructor to kill all the graphics instead of having to imagedestroy each individual one.

only thing is that because you use a string as an identifier I'm having to write lots of strings.

eg.

Code: Select all

pic.load Char(1).pic(E).frame(1), "\GFX\chareast1.bmp"  'is to load the first frame of a character facing east.

                                                        'Char(1).pic(E).frame(1) has to be a string that's different from say Char(1).pic(E).frame(2)
                                                        'so I'd have to write

Char(1).pic(E).frame(1) = "firstframefacingeast" 'or something. Different strings for every single frame in every single direction for every single character.
any ideas on how to get around that?

Posted: Wed May 06, 2009 3:41 am
by Hrothgar
the put # thing.

Code: Select all

DIM fileno as integer
PRINT "writing a file."
fileno = freefile                                    ' finds the first available free file
OPEN "somefile.txt" for output as fileno             ' opens a text file for output or creates one if it doesn't exist
        PUT #fileno, 1, "Blah Blah"                  ' writes Blah Blah in the file at position 1
        PUT #fileno, 10, "Blah Blah"                 ' writes Blah Blah in the file at position 10
CLOSE fileno 
SLEEP
this only writes things to the first line of the text file. How can I write to other lines?


EDIT: doesn't matter I used PRINT # instead

Posted: Wed May 06, 2009 11:22 am
by T'lon Nanaki
here is a quick edit so id accepts integers

open anybmp and in the bmp_struc type make id read

dim as integer id

then use the replace funcion in the editor and have it replace "id as string" with "id as integer" and it should accept integers instead of strings
just be sure that you don't use the same value for multiple graphics (it'll only return the first one entered sence id is used to IDentify each graphic)

as for the file thing:
using put # will alway make a 'one line' file sence the format is linear
i'd go with print #/write # like you mentioned for multilined entries