Turn Based Games
Turn Based Games
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.
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.
- T'lon Nanaki
- Coder
- Posts: 42
- Joined: Mon Aug 04, 2008 12:46 pm
- Location: Denver Colorado
- Contact:
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
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
carpe diem!
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)
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)
- T'lon Nanaki
- Coder
- Posts: 42
- Joined: Mon Aug 04, 2008 12:46 pm
- Location: Denver Colorado
- Contact:
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.
shouldn't this make a healthbar for character 1 with an alpha transparency of 100? why is it just solid green?
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
- T'lon Nanaki
- Coder
- Posts: 42
- Joined: Mon Aug 04, 2008 12:46 pm
- Location: Denver Colorado
- Contact:
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
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)![Smile :)](./images/smilies/icon_smile.gif)
let me know if this helped...
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
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)
![Smile :)](./images/smilies/icon_smile.gif)
let me know if this helped...
carpe diem!
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?
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?
- T'lon Nanaki
- Coder
- Posts: 42
- Joined: Mon Aug 04, 2008 12:46 pm
- Location: Denver Colorado
- Contact:
- T'lon Nanaki
- Coder
- Posts: 42
- Joined: Mon Aug 04, 2008 12:46 pm
- Location: Denver Colorado
- Contact:
- T'lon Nanaki
- Coder
- Posts: 42
- Joined: Mon Aug 04, 2008 12:46 pm
- Location: Denver Colorado
- Contact:
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
![Smile :)](./images/smilies/icon_smile.gif)
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
carpe diem!
- T'lon Nanaki
- Coder
- Posts: 42
- Joined: Mon Aug 04, 2008 12:46 pm
- Location: Denver Colorado
- Contact:
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
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
carpe diem!
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.
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.
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.
- T'lon Nanaki
- Coder
- Posts: 42
- Joined: Mon Aug 04, 2008 12:46 pm
- Location: Denver Colorado
- Contact:
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![Smile :)](./images/smilies/icon_smile.gif)
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!))
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
![Smile :)](./images/smilies/icon_smile.gif)
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!))
carpe diem!
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.
any ideas on how to get around that?
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.
Last edited by Hrothgar on Wed May 06, 2009 3:46 am, edited 2 times in total.
the put # thing.
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
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
EDIT: doesn't matter I used PRINT # instead
- T'lon Nanaki
- Coder
- Posts: 42
- Joined: Mon Aug 04, 2008 12:46 pm
- Location: Denver Colorado
- Contact:
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
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
carpe diem!