ACW wargame

Community Forums/Showcase/ACW wargame

Mainsworthy(Posted 2017) [#1]
I toned down the background. And the units face in 6 directions, so graphics have to work with it, but I'm taking all suggestions in as I go.. its not great graphics yet but here is the wargame working .

https://numbergamer8.itch.io/acw-war




Blitzplotter(Posted 2017) [#2]
Great stuff, it shows a lot of promise ;)


Mainsworthy(Posted 2017) [#3]
Thx BP, I really am enjoying it


AdamStrange(Posted 2017) [#4]
i'm not saying anything, but posting a googles rts hex image for you to think over



Mainsworthy(Posted 2017) [#5]
Adam your that good at graphics, I thought at first you just threw this together in a few minites. I'm definatly taking what you mean, even a little hex game can look incredible, Ive got this so far, remember I have to make the game work with the graphics, eg 6 facing sides for each unit,I also added destructible walls, so you can see I cant just put in what looks good it has to work too top down seems ok, but Ive programed in a 3D capable system for different views of the unit in each of its facing




AdamStrange(Posted 2017) [#6]
ok, out of interest how are you (internally dealing with the hex data?

You've given me the hex bug and I'm working on something very small with a hex grid, but I decided to stick with just a standard x,y array. Here's a pic showing what I am doing:


so going up/down is just using the y axis, left/right has four cells to pick from. E.G.
if you are at cell 1,2. you can move right to 2,1 or 2,2


Mainsworthy(Posted 2017) [#7]
the 2 programs below are basically all you need to do a hex game, the hex grid is like you drew squares one row halfway down than the other. you just add mapx and mapy to the window your looking at to move around.


'you must provide 2 files for this program to work troops.png 20 pixels high 40 across 2 chits
'a 1024x768 backdrop

Graphics 1024,768,32,60
Global chit = LoadAnimImage(".\troops.PNG",20,20,0,2,flags=ALPHABITS ) '2 twenty by twenty chits
Global backdrop = LoadImage(".\backdrop.PNG" ) 'plain backdrop

Global gameboard[10,10,20] '10 x 10 grid gameboard with 20 items of info per location
Global x1 = 0
Global y1 = 0
'try setting the gameboard as shown below
gameboard[1,1,1] = 1
gameboard[1,3,1] = 1


While Not KeyHit(KEY_ESCAPE) 'hit escape to exit

Cls 'clear screen before redrawing each loop through

DrawImage(backdrop ,0,0) 'draw backdrop

'use a for next loop to draw chits
For x= 0 To 9
For y = 0 To 9
If gameboard[x,y,1] = 1 Then DrawImage(chit,x*20,y*20,frame=1) 'frame is chit number
Next
Next

' devise x and y by 20 pixels, this is because the chits are 20 pixels
'the idea is to find where the mouse pointer is
x1 = MouseX() /20
y1 = MouseY() /20

'this sets gameboard on off by left or right clicking
If x1 < 10 And x1 > -1 And y1 < 10 And y1 > -1
If MouseDown(1) 'Left click set on
gameboard[x1,y1,1] = 1
EndIf
If MouseDown(2) 'right click set off
gameboard[x1,y1,1] = 0
EndIf
EndIf



Flip 'this flips the board onto the screen

Wend

End
=================================================================
now the same program in hex, and it has mouse detection etc
=================================================================
'this is a hexgrid, with 40x40 size
'you must provide 2 files for this program to work troops.png 40 pixels high 80 across 2 chits
'a 1024x768 backdrop

Graphics 1024,768,32,60
Global chit = LoadAnimImage(".\HexGame\troops.PNG",40,40,0,2,flags=ALPHABITS ) '2 forty by forty chits
Global backdrop = LoadImage(".\HexGame\backdrop.PNG" ) 'plain backdrop

Global gameboard[40,40,40] '40 x 40 grid gameboard with 40 items of info per location
Global x1 = 0
Global y1 = 0
Global shift = 0

Global sa = 0
Global ba = 0

'try setting the gameboard as shown below
gameboard[1,1,1] = 1
gameboard[1,3,1] = 1


While Not KeyHit(KEY_ESCAPE) 'hit escape to exit

Cls 'clear screen before redrawing each loop through


DrawImage(backdrop ,0,0) 'draw backdrop

drawhexgrid() 'call the function to draw hexgrid







x1 = MouseX() /40
y1 = MouseY() /40

'this adjusts the code for a hexgrid rather than squares
shift = 0 'initialise shift
If x1 = 0 Or x1 = 2 Or x1 = 4 Or x1 = 6 Or x1 = 8 Or x1 = 10 Or x1 = 12 Or x1 = 14 Or x1 = 16 Or x1 = 18 Or x1 = 20 Or x1 = 22 Or x1 = 24 Or x1 = 26 Then shift = 1
If shift = 1
y1 = (MouseY()-20) /40 '-20 because the +20 we added in the display loop and the mousey
EndIf

'use a for next loop to draw chits
For x= 0 To 26
For y = 0 To 16

shift = 0 'initialise shift
If x = 0 Or x = 2 Or x = 4 Or x = 6 Or x = 8 Or x = 10 Or x = 12 Or x = 14 Or x = 16 Or x = 18 Or x = 20 Or x = 22 Or x = 24 Or x = 26 Then shift = 1 'check to see if we are on a shifted down hex
If gameboard[x,y,1] = 1 And shift = 0 Then DrawImage(chit,x*40,y*40,frame=1) 'frame is chit number 1 or 2
If gameboard[x,y,1] = 1 And shift = 1 Then DrawImage(chit,x*40,(y*40)+20,frame=1) 'frame is chit number 1 or 2, adds 10 to Y(down)

Next
Next

' devise x and y by 20 pixels, this is because the chits are 20 pixels
'the idea is to find where the mouse pointer is




'this sets gameboard on off by left or right clicking
If x1 < 25 And x1 > 0 And y1 < 16 And y1 > -1 'x has 25 across, y has 16 down
If MouseDown(1) 'Left click set on
gameboard[x1,y1,1] = 1
EndIf
If MouseDown(2) 'right click set off
gameboard[x1,y1,1] = 0
EndIf
EndIf



Flip 'this flips the board onto the screen

Wend



End

Function drawhexgrid()

' the loops draw 6 hexsides and repeat through the loops

a = 80
b = 0
c = 80
d = 0

For a2 = 0 To 15
For a1 = 0 To 26 Step 2
DrawLine(5+a,20+b,35+c,20+d)
DrawLine(35+a,20+b,45+c,40+d)
DrawLine(45+a,40+b,35+c,60+d)
DrawLine(35+a,60+b,5+c,60+d)
DrawLine(5+a,60+b,-5+c,40+d)
DrawLine(-5+a,40+b,5+c,20+d)
a=a+80
c=c+80
Next
a = 80
c = 80
b = b+40
d = d+40
Next

a = 40
b = -20
c = 40
d = -20

For a2 = 0 To 15
For a1 = 0 To 23 Step 2
DrawLine(5+a,20+b,35+c,20+d)
DrawLine(35+a,20+b,45+c,40+d)
DrawLine(45+a,40+b,35+c,60+d)
DrawLine(35+a,60+b,5+c,60+d)
DrawLine(5+a,60+b,-5+c,40+d)
DrawLine(-5+a,40+b,5+c,20+d)
a=a+80
c=c+80
Next
a = 40
c = 40
b = b+40
d = d+40
Next





End Function

End


AdamStrange(Posted 2017) [#8]
I'm using a slightly different way of drawing my stuff:


each y portion draws two horizontal rows.
first the even numbered x
the the odd numbered x (now offset down)

so there are two cell drawing parts - odd and even which have slightly different y and x offsets.

(I think you are drawing 2 vertical rows at once?)

There is a logic to this:
when we draw a hex cell, we can draw any contents, so first the cell, then some dressing, and lastly the figure (if one is present)

we then draw the next right one and then the next row below. so everything will layer correctly. trees are always infant of other trees, etc

Here's a pic to show what I mean:


we have some base graphics and some tree graphics
on the left is a standard grid arrangement, and on the right is the offset hex arrangement.
drawing a tree on a hex obscure what's behind it, so you draw what's behind first
as each cell is correctly aligned I just draw the entire contents of the hex cell and any dressing at the same time then move onto the next cell to draw

NOTE
I am using the same graphics and colouring them, so there is only one tree not 2. the same for the hex cell themselves - being coloured.


Derron(Posted 2017) [#9]
mainsworthy:

'use a for next loop to draw chits
For x= 0 To 9 
For y = 0 To 9 
If gameboard[x,y,1] = 1 Then DrawImage(chit,x*20,y*20,frame=1) 'frame is chit number
Next
Next

[...]

Graphics 1024,768,32,60
Global chit = LoadAnimImage(".\HexGame\troops.PNG",40,40,0,2,flags=ALPHABITS ) '2 forty by forty chits



(and other portions in your sample)

I doubt it is really doing what it should. What you do is, to pass the result of the comparison "flags=ALPHABITS" as the param, so as soon as flags is not just containing "ALPHABITS", it will be "0" (false).

I assume you want do so something like an assignment ("frame = 1", and then pass "frame").


See this example:

'without declaration "frame" is "0", so "frame=0" is "true" (=> "1")
PrintParam(20,20,frame=0)
'without declaration "frame" is "0", so "frame=1" is "false" (=> "0")
PrintParam(20,20,frame=1)

Function PrintParam(x:Int, y:Int, frame:Int=0)
	Print "x=" + x + "  y=" + y + "  frame=" + frame
End Function

When executing you will see that the first param is not printing "frame=1" but "frame=0" - and the second is doing the opposite.




@ AdamStrange
Important step is missing: a unit might move (animate) to another cell, so it should be "visually attached" (not logically - like "standing on grid x,y") to the most right tile it collides with (bounding-box / x,y + spriteWidth/Height). Else a more right positioned tile might draw over the moving unit.
The easiest thing to achieve this is to store the "targetGrid"-information for a unit, and when drawing checking wether the targetGrid is drawn later than the currentGrid.

Regarding Colorizing trees - in that case a "SetColor" is a bit too much tinting. Either split "stem" and "leafs" so you can draw and mix them (two stem sprites, some different shapes for the tree) and even colorize them a bit randomly. Or you draw the leafs in a replaceable-color and let a software prepare multiple sprites on start. I suggested my Dig-frameworks imagehelper-class a while ago. It colorizes gray parts. To have "gray" parts not colorized, you need to add a little bit of blue/red... eg. 204,200,200 will stay untouched.
The second suggestion allows to store them all on a single spritesheet/texture and saves on draw-calls but of course is less dynamic than a "mix from various pieces" thing.


bye
Ron


Derron(Posted 2017) [#10]
Oh I just forgot:


Function drawhexgrid()

' the loops draw 6 hexsides and repeat through the loops

a = 80
b = 0
c = 80
d = 0

For a2 = 0 To 15 
For a1 = 0 To 26 Step 2
DrawLine(5+a,20+b,35+c,20+d)
DrawLine(35+a,20+b,45+c,40+d)
DrawLine(45+a,40+b,35+c,60+d)
DrawLine(35+a,60+b,5+c,60+d)
DrawLine(5+a,60+b,-5+c,40+d)
DrawLine(-5+a,40+b,5+c,20+d)
a=a+80
c=c+80
Next
a = 80
c = 80
b = b+40
d = d+40
Next

a = 40
b = -20
c = 40
d = -20

For a2 = 0 To 15 
For a1 = 0 To 23 Step 2
DrawLine(5+a,20+b,35+c,20+d)
DrawLine(35+a,20+b,45+c,40+d)
DrawLine(45+a,40+b,35+c,60+d)
DrawLine(35+a,60+b,5+c,60+d)
DrawLine(5+a,60+b,-5+c,40+d)
DrawLine(-5+a,40+b,5+c,20+d)
a=a+80
c=c+80
Next
a = 40
c = 40
b = b+40
d = d+40
Next




This is absolute overkill... each frame you render 2496 lines. Means 2500 draw calls.


I think drawing pre-made grid-boundaries is faster - and allows for a visually more pleasing look (remember the grid-tile-boundaries I suggested in one of your other games?).
Eg. that "3d-ish" look (highlights and shadows of the tiles) could be easily achieved with an overlay-image.
So the result would be to replace the 6 Drawlines (and their calculations) with one "DrawImage" (or in your case - without decorations and multiple "layers" and a "draw all tiles then draw all units"-approach you could even have multiple grids drawn next to each other so to draw "X*Y" cells in one draw-call, and only do single-grid-overlay-draw on the start and ending grid cells).

For now your FPS wont be that low, but if you add more "decoration" or other visually pleasing things, the more your app has to do - leading to low FPS somewhen (or it just runs sluggish on older computers).


While this now sounds as if I was here to tell you about performance, no I am here to point out that your code contains things which could be done in a "better" way.


Things like this:


'this sets gameboard on off by left or right clicking
If x1 < 25 And x1 > 0 And y1 < 16 And y1 > -1 'x has 25 across, y has 16 down
If MouseDown(1) 'Left click set on
gameboard[x1,y1,1] = 1
EndIf
If MouseDown(2) 'right click set off
gameboard[x1,y1,1] = 0
EndIf
EndIf



What is this supposed to do?
If button 1 is hold down, variable is set to "1"
if button 2 is hold down, (the same!) variable is set to "0"

What happens if no button is hold down?

If you really want to store both information in one value, you need to use bitmasks (0,1,2,4,8,16. So nothing=0, only option1=1, only option2=2, option1+option2=3, option1+option2+option3=1+2+4=7, option1+option3=5)

Or in your case, just use a different third array index (,1 for button1 and ,2 for button2)
And then: do not forget to reset the variables accordingly.

gameboard[x1,y1,1] = MouseDown(1)
gameboard[x1,y1,2] = MouseDown(2)
So if mouse was down, then the first contains "true", else it is set to "false". Same for button 2.



bye
Ron


TomToad(Posted 2017) [#11]
This book has helped me with programming hex tile games.
It is an old book, so you might have a bit of trouble finding a new copy. I was able to locate used copies for sale from several vendors.

It's useful for both isometric games and hex games, as it treats hex tiles the same as isometric tiles, just a different shape.


Mainsworthy(Posted 2017) [#12]
Let me explain a few things, first
Global chit = LoadAnimImage(".\HexGame\troops.PNG",40,40,0,2,flags=ALPHABITS ) '2 forty by forty chits , Normaly I may have 100 chits, I use frame=0 to delete the chit or hextile, it saves writing code all you do is normally pick a chit(chit 0) and place it on the map and the old chit disappears.

Adam, the array must be in sequence if you ever hope to do an A.I. that calculates( you do an A.I. like tic tac toe, do a loop and test each cell for events and then move if so etc.. the A.I. is a personal thing as you go you build it bit by bit test by test, it is just a question of methodicaly doing a tic tac toe) . If I remember right there are a few ways to do similar thins your doing, first one is use hex bits not a full hex( eg top half, or bottom half. or hex edges), so you would paste over the topmost bit last, second use are that only spans the center of the hex, third only bleed into the left side of the hex so all hexes leave the right side for the next hex. its not the array that I have shown is wrong its that you need a display loop.

this is an amazing tip gameboard[x1,y1,1] = MouseDown(1)
gameboard[x1,y1,2] = MouseDown(2) and the FPS has never bothered me as its turn based but on some games the maps get slow because of flipping the screen rather than draws, and I don't always use lines I do use art a lot, its the principal of a hexgame distilled I was trying to show.

Tom, that's great info isometric like hex, if the display loop works for one it will work for both, I have not read a book for a while, but people have done this stuff before and wrote it down, so its a good idea to have a book


skidracer(Posted 2017) [#13]
M, if you are going to continue creating threads in Showcase can you please put a little more effort into your project titles. ACW wargame tells me nothing except you like to make other people feel ignorant by using acronyms in inappropriate contexts.

Is the hex bug contagious? I have only suffered the quad version.

   ****
  ********
 ********
    ****



Derron(Posted 2017) [#14]
@ sequence and AI
the AI wont bother how you tackle "drawing/updating". An AI always should be able to request information about neighboring tiles. HOW these tiles are stored in the game is not of interest. A unit just does a "GetTileInfo(-1,0)" to ask for the "left" one" and so on. The game then is doing whatever is needed to provide the given information.


@ loadanimimage
I still do not get how you delete a "chit/hextile" with a "flag=Variable"-thing passed as param?

Maybe you did not understand what I tried to express - so please check out the example I have given in my last post. It should really explain it well enough.

print(frame=3)
does not print "3", it prints "0" as "frame" is not initialized and therefor "0", and the comparison "0=3" is "false", which is expressed as "0" in BlitzMax.

So if you want to assign something then you need to do it a step earlier:
frame=3
print(frame)



bye
Ron