Sign in to follow this  
Followers 0
mvendak

Faster display for this game?

11 posts in this topic

I wrote this small rouge like game concept, but before i add features, it would be nice to find a faster way to update the GUI. It is based on Ichigo's

grid udf idea.

CODE

#include <GUIConstantsEx.au3>

Global $xGrid[1][1] ; an array containing all the control ID's for each item, Ichigo's grid udf

Global $dungeonFloor[1][1] ;$dungeonFloor values may actually represent something other than floor (walls/black space/door), it would be more accurate the call it first layer (the only layer at this point)

Global $dungeonExplored[1][1] ;squares already seen are rememberd by the character, so theres a picture there according to the squares "floor" type (floor/wall/etc)

Global $dungeonMob[1][1] ;ids of mobs

Global $dungeonItems[1][1][20] ;to be implemented

Global $charpos[2] ;main chars xy

Global $images[3][100] ;collection of image paths used, 0 is black, 1 is default floor, 2 is default wall, 3 is our hero; needs to be split up to diffrent arrays for different types (floor/character/monster)

Global $monster, $floor ; values set by _getSquareType()

Global $mobs[100][10] ;identifiers of mobs, at each step they can move/hit in a random direction, [0][0] is their counter

;FileInstalls here

$maingui = GUICreate('game',900,550)

$textbox = GUICtrlCreateLabel("Welcome!",10,400,800,50)

$helpmenu = GUICtrlCreateMenu("Help")

$fileitem = GUICtrlCreateMenuItem("Info", $helpmenu)

GUICtrlSetState(-1, $GUI_DEFBUTTON)

$images[0][0]= @ScriptDir&"\Img\black.bmp"

$images[0][1]= @ScriptDir&"\Img\floor.bmp"

$images[0][2]= @ScriptDir&"\Img\wall.bmp"

$images[0][3]= @ScriptDir&"\Img\door.bmp"

$images[1][0]= @ScriptDir&"\Img\hero.bmp"

$images[1][1] = @ScriptDir&"\Img\mons1.bmp"

$images[1][2] = @ScriptDir&"\Img\mons2.bmp"

$images[2][1] = @ScriptDir&"\Img\lada1.bmp"

$images[2][2] = @ScriptDir&"\Img\címmerpajzs1.bmp"

_CreateLevel_Memory(50,20)

_CreateLevel_Gui(50, 20, 18, $maingui)

$label = GUICtrlCreateLabel("",0,360,900,30)

GUICtrlSetBkColor($label,0x050505)

GUISetState(@SW_SHOW)

;HotKeySet("w","Test1")

;HotKeySet("s","Test2")

;HotKeySet("a","Test3")

;HotKeySet("d","Test4")

while 1

Select

Case _IsPressed(57)

_MoveCharacter("up")

sleep(50)

Case _IsPressed(41)

_MoveCharacter("left")

sleep(50)

Case _IsPressed(53)

_MoveCharacter("down")

sleep(50)

Case _IsPressed(44)

_MoveCharacter("right")

sleep(50)

Case 1

sleep(100)

EndSelect

WEnd

Func _CreateLevel_Gui($x, $y, $size, $gui) ;visualization of the "dungeon" as a grid of pictures. Based on the Grid UDF made by Ichigo

If $x < 0 or $y < 0 or $size < 0 then Return -1

GUICtrlCreatePic($images[1][0], $charpos[0] * $size, $charpos[1] * $size, $size, $size)

ReDim $xGrid[$x][$y]

$bX = $x

$bY = $y

GUISwitch($gui)

For $x = 0 to $bX - 1

For $y = 0 to $bY - 1

if $dungeonExplored[$x][$y] = 0 then

$xGrid[$x][$y] = GUICtrlCreatePic($images[0][0], $x * $size, $y * $size, $size, $size) ;most of the place is black...

Else

$xGrid[$x][$y] = GUICtrlCreatePic($images[0][0], $x * $size, $y * $size, $size, $size) ;however, a few blocks are already "seen" by the mainchar at startup

_RenderGrid($x,$y)

EndIf

Next

Next

Return 1

EndFunc

Func _CreateLevel_Memory($sizex, $sizey) ;creating the floor and a little house/fort/whatever for the character to start in. Some algorith to generate a level goes here

ReDim $dungeonExplored[$sizex][$sizey]

ReDim $dungeonFloor[$sizex][$sizey]

ReDim $dungeonItems[$sizex][$sizey][20]

ReDim $dungeonMob[$sizex][$sizey]

$charpos[0] = 5 ;Random(1,10,1)

$charpos[1] = 1 ;Random(1,10,1)

_CreateRoom(0,0,10,10,0,5,5,0)

_CreateRoom(9,4,10,3,4,1,0,0) ;folyosó

_CreateRoom(9,6,8,9,4,0,4,0)

_CreateRoom(0,10,10,10,5,5,0,0)

_CreateRoom(9,14,10,3,0,1,4,0)

_CreateRoom(18,0,20,20,0,10,0,10) ;bigroom

_CreateRoom(25,8,5,5,0,2,0,2)

_CreateRoom(29,8,5,5,0,2,0,2)

_CreateRoom(33,8,5,5,0,2,0,2);kicsi

for $x=0 to $sizex -1

for $y=0 to $sizey -1

If $dungeonFloor[$x][$y] = 1 OR $dungeonFloor[$x][$y] = "" And 3 > Random(0,99,1) Then ;on each floor type square already set by_createRoom

$type = Random(1,2,1) ;3% chance for a random type monster to appear (only 2 types here)

_SpawnMob($x,$y,$type)

EndIf

if $dungeonFloor[$x][$y] = "" Then ;this is needed so the default squre type wont override rooms/corridors created before (not implemented yet)

$dungeonFloor[$x][$y] = 1 ;set everything to 1, walkable floor.

$dungeonExplored[$x][$y] = 0 ;nothing is explored yet

EndIf

Next

; MsgBox(0,"lol",$x &"x-y"&$y)

Next

For $x = -1 to 1

for $y = -1 to 1

$dungeonExplored[$charpos[0] + $x][$charpos[1] + $y] = 1 ;the squares next to the character start as explored

Next

Next

EndFunc

Func _SpawnMob($x,$y,$type)

$mobs[0][0] +=1

$dungeonMob[$x][$y] = $mobs[0][0]

$mobs[$mobs[0][0]][0] = $type ;type of the mob == number of the image that gets rendered

$mobs[$mobs[0][0]][1] = Random(1,3,1) ;hp 1-3

$mobs[$mobs[0][0]][2] = $x

$mobs[$mobs[0][0]][3] = $y

$loot1 = Random(1,2,1)

$mobs[$mobs[0][0]][4] = $loot1

$mobs[$mobs[0][0]][5] = ""

EndFunc

Func _KillMob($id)

$mobs[$id][0] = ""

$mobs[$id][1] = 0 ;hp

$dungeonMob[$mobs[$id][2]][$mobs[$id][3]] = ""

$dungeonItems[$mobs[$id][2]][$mobs[$id][3]][0] += 1

$itemnumber = $dungeonItems[$mobs[$id][2]][$mobs[$id][3]][0]

$dungeonItems[$mobs[$id][2]][$mobs[$id][3]][$itemnumber] = $mobs[$id][4]

$mobs[$id][2] = -1

$mobs[$id][3] = -1

EndFunc

Func _HitMob($id)

$mobs[$id][1] -= 1

If $mobs[$id][1] = 0 Then _KillMob($id)

EndFunc

Func _MobMove()

For $mob = 1 to $mobs[0][0]

$direction = Random(1,5,1)

$tempx = $mobs[$mob][2]

$tempy = $mobs[$mob][3]

If $tempx = -1 Then ContinueLoop ;halott szörnyek nem ugrálnak

Switch $direction

Case 1 ;"left"

$left = _getSquareType($mobs[$mob][2] - 1,$mobs[$mob][3])

If $left = -1 Then $direction = 3

If $left = 1 And $floor = 2 Then $direction = 3

If $left = 1 AND $floor = 1 Then $mobs[$mob][2] -= 1

If $left = 1 And $floor = 3 AND 101 > Random(1,100) Then _OpenDoor($mobs[$mob][2] - 1,$mobs[$mob][3])

If $left = 2 And $monster <> $mobs[$mob][0] Then _HitMob($monster)

Case 2; "right"

$right = _getSquareType($mobs[$mob][2] + 1,$mobs[$mob][3])

If $right = -1 Then $direction = 4

If $right = 1 And $floor = 2 Then $direction = 4

If $right = 1 AND $floor = 1 Then $mobs[$mob][2] += 1

If $right = 1 And $floor = 3 AND 101 > Random(1,100) Then _OpenDoor($mobs[$mob][2]+1,$mobs[$mob][3])

If $right = 2 And $monster <> $mobs[$mob][0] Then _HitMob($monster)

Case 3; "up"

$up = _getSquareType($mobs[$mob][2] ,$mobs[$mob][3]- 1)

If $up = -1 Then $direction = 4

If $up = 1 And $floor = 2 Then $direction = 4

If $up = 1 AND $floor = 1 Then $mobs[$mob][3] -= 1

If $up = 1 And $floor = 3 AND 101 > Random(1,100) Then _OpenDoor($mobs[$mob][2],$mobs[$mob][3] - 1)

If $up = 2 And $monster <> $mobs[$mob][0] Then _HitMob($monster)

Case 4; "down"

$down = _getSquareType($mobs[$mob][2],$mobs[$mob][3] + 1)

If $down = -1 Then $direction = 1

If $down = 1 And $floor = 2 Then $direction = 1

If $down = 1 AND $floor = 1 Then $mobs[$mob][3] += 1

If $down = 1 And $floor = 3 AND 101 > Random(1,100) Then _OpenDoor($mobs[$mob][2],$mobs[$mob][3]+1)

If $down = 2 And $monster <> $mobs[$mob][0] Then _HitMob($monster)

EndSwitch

;IF $

$dungeonMob[$tempx][$tempy] = ""

$dungeonMob[$mobs[$mob][2]][$mobs[$mob][3]] = $mob

Next

EndFunc

Func _CreateRoom($startx, $starty, $sizex , $sizey, $fal1 = 0,$fal2 = 0,$fal3 = 0,$fal4 = 0) ;creates a square room. last variable is the side of the room to have its door on

$sizex -= 1 ;room dimensions corretion, so _CreateRoom(10, 10, 4 , 4) is a 4x4 room rather then a 5x5

$sizey -= 1

$x = $startx

for $y=$starty to $sizey + $starty ;top wall

If $dungeonFloor[$x][$y] <> 3 Then

$dungeonFloor[$x][$y] = 2

$dungeonExplored[$x][$y] = 0

EndIf

Next

for $x = $startx + 1 to $sizex + $startx ; everything else, walls on the starting and ending position

$y=$starty

If $dungeonFloor[$x][$y] <> 3 Then

$dungeonFloor[$x][$y] = 2

$dungeonExplored[$x][$y] = 0

EndIf

for $y=$starty + 1 to $sizey + $starty

If $dungeonFloor[$x][$y] <> 3 Then

$dungeonFloor[$x][$y] = 1

$dungeonExplored[$x][$y] = 0

EndIf

Next

$y=$sizey + $starty

If $dungeonFloor[$x][$y] <> 3 Then

$dungeonFloor[$x][$y] = 2

$dungeonExplored[$x][$y] = 0

EndIf

Next

$x = $startx + $sizex

for $y=$starty to $sizey + $starty ;bottom wall

If $dungeonFloor[$x][$y] <> 3 Then

$dungeonFloor[$x][$y] = 2

$dungeonExplored[$x][$y] = 0

EndIf

Next

If $fal1 > 0 Then ;if top wall

$hol = $fal1

If $dungeonFloor[$startx+ $hol][$starty] <> 1 Then

$dungeonFloor[$startx+ $hol][$starty] = 3

EndIf

EndIf

If $fal2 > 0 Then ;if right wall

$hol = $fal2

If $dungeonFloor[$startx + $sizex][$starty+ $hol] <> 1 Then

$dungeonFloor[$startx + $sizex][$starty+ $hol] = 3

EndIf

EndIf

If $fal3 > 0 Then ;if bottom wall

$hol = $fal3

If $dungeonFloor[$startx + $hol][$starty+ $sizey] <> 1 Then

$dungeonFloor[$startx+ $hol][$starty + $sizey] = 3

EndIf

EndIf

If $fal4 > 0 Then;if left wall

$hol = $fal4

If $dungeonFloor[$startx][$starty+ $hol] <> 1 Then

$dungeonFloor[$startx][$starty+ $hol] = 3

EndIf

EndIf

EndFunc

Func _MoveCharacter($direction) ;Character tries to go in a certain direction. To do: split up to more functions, so other objects (monsters?) may access those functions

$temp = $xGrid[$charpos[0]][$charpos[1]] ;point where he tries to move from

Switch $direction

Case "left"

$left = _getSquareType($charpos[0] - 1,$charpos[1])

If $left = -1 Then Return 0

If $left = 1 And $floor = 2 Then return 0

If $left = 1 AND $floor = 1 Then $charpos[0] -= 1

If $left = 1 And $floor = 3 Then _OpenDoor($charpos[0] - 1,$charpos[1])

If $left = 2 THen _HitMob($monster)

Case "right"

$right = _getSquareType($charpos[0] + 1,$charpos[1])

If $right = -1 Then Return 0

If $right = 1 And $floor = 2 Then return 0

If $right = 1 AND $floor = 1 Then $charpos[0] += 1

If $right = 1 And $floor = 3 Then _OpenDoor($charpos[0]+1,$charpos[1])

If $right = 2 THen _HitMob($monster)

Case "up"

$up = _getSquareType($charpos[0] ,$charpos[1]- 1)

If $up = -1 Then Return 0

If $up = 1 And $floor = 2 Then return 0

If $up = 1 AND $floor = 1 Then $charpos[1] -= 1

If $up = 1 And $floor = 3 Then _OpenDoor($charpos[0],$charpos[1] - 1)

If $up = 2 THen _HitMob($monster)

Case "down"

$down = _getSquareType($charpos[0],$charpos[1] + 1)

If $down = -1 Then Return 0

If $down = 1 And $floor = 2 Then return 0

If $down = 1 AND $floor = 1 Then $charpos[1] += 1

If $down = 1 And $floor = 3 Then _OpenDoor($charpos[0],$charpos[1]+1)

If $down = 2 THen _HitMob($monster)

EndSwitch

_MobMove()

Switch $direction ;de-render monsters

case "up"

For $x = -3 to 3

_RenderGrid($charpos[0]+$x,$charpos[1]+4, 3)

Next

case "down"

For $x = -3 to 3

_RenderGrid($charpos[0]+$x,$charpos[1]-4, 3)

Next

case "left"

For $x = -3 to 3

_RenderGrid($charpos[0]+4,$charpos[1]+$x, 3)

Next

case "right"

For $x = -3 to 3

_RenderGrid($charpos[0]-4,$charpos[1]+$x, 3)

Next

EndSwitch

For $y = -3 to 3 ;render your new surroundings: set those squres to explored, and show their picture accoring to "floor" value

for $x = -3 to 3

;$temp = _getSquareType($charpos[0]-$x,$charpos[1]-$y)

;sleep(50)

_RenderGrid($charpos[0]-$x,$charpos[1]-$y)

Next

Next

EndFunc

Func _getSquareType($x,$y) ;sets $floor to floor type and returns 1, or returns 2 and sets $monster id if a monster is there

If $y >= 0 And $x >=0 AND $x < UBound($xGrid,1) AND $y < UBound($xGrid,2) Then

Select

Case $x = $charpos[0] AND $y = $charpos[1]

return 0

Case $dungeonMob[$x][$y] <> ""

$monster = $dungeonMob[$x][$y]

Return 2

Case $dungeonFloor[$x][$y] <> ""

$floor = $dungeonFloor[$x][$y]

return 1

EndSelect

Else

Return -1

EndIf

EndFunc

Func _RenderGrid($x,$y,$exclude = "")

If $y >= 0 And $x >=0 AND $x < UBound($xGrid,1) AND $y < UBound($xGrid,2) Then ;errors avoided

$img_f = $dungeonFloor[$x][$y]

$img_i = $dungeonItems[$x][$y][0]

$img_m = $dungeonMob[$x][$y]

If $exclude = 1 Then $img_f = ""

If $exclude = 2 Then $img_i = 0

If $exclude = 3 Then $img_m = ""

Select

case $x = $charpos[0] And $y = $charpos[1]

GUICtrlSetImage($xGrid[$x][$y], $images[1][0])

case $img_m <> ""

$img_m = $mobs[$img_m][0]

GUICtrlSetImage($xGrid[$x][$y], $images[1][$img_m])

case $img_i <> 0

$img_i = $dungeonItems[$x][$y][$img_i]

GUICtrlSetImage($xGrid[$x][$y], $images[2][$img_i])

case $img_f <> ""

GUICtrlSetImage($xGrid[$x][$y], $images[0][$img_f])

EndSelect

If $dungeonExplored[$x][$y]=0 Then $dungeonExplored[$x][$y]=1

Else

return 0

EndIf

EndFunc

Func _OpenDoor($bX,$bY)

$kocka = Random(0,100,1) ;d100 dice to get success of door "opening" (right now: smashing)

Switch $kocka

Case 1 to 75 ; 3 out of 4, you fail

return 0

case 76 to 100 ;you smash the door

$dungeonFloor[$bX][$bY] = 1 ;the door there is now a floor

return 2

EndSwitch

EndFunc

Func Test1()

_MoveCharacter("up")

EndFunc

Func Test2()

_MoveCharacter("down")

EndFunc

Func Test3()

_MoveCharacter("left")

EndFunc

Func Test4()

_MoveCharacter("right")

EndFunc

Func _IsPressed($hexKey)

; $hexKey must be the value of one of the keys.

; _IsPressed will return 0 if the key is not pressed, 1 if it is.

; $hexKey should entered as a string, don't forget the quotes!

; (yeah, layer. This is for you)

Local $aR, $bO

$hexKey = '0x' & $hexKey

$aR = DllCall("user32", "int", "GetAsyncKeyState", "int", $hexKey)

If Not @error And BitAND($aR[0], 0x8000) = 0x8000 Then

$bO = 1

Else

$bO = 0

EndIf

Return $bO

EndFunc ;==>_IsPressed

My problem is with the _RenderGrid() function: right now it is used on a 7x7 + 7 square area each time the main character takes a step, but if i use it on more (a whole room the character is in, etc), it takes too much time for all the squares to change picture, and its not very fast as it is neither. Is there a way to get the path of the picture used by a picture type gui control, so i save time by only redrawing those that actually changed? Or should I temporarly store the currently shown square's monster>item>"floor" type before a step, and compare that to the value to the value it has after the step? I think this would be just as slow as it is now, or even slower. Any ideas welcome, thx in advance :)

Pictures i use for this:

Img.rar

Share this post


Link to post
Share on other sites



I modified it a bit, the time it takes to display is better and can still be improved, but I am tired and must sleep, so here it is...

#include <GUIConstantsEx.au3>
Global $xGrid[1][1] ; an array containing all the control ID's for each item, Ichigo's grid udf
Global $dungeonFloor[1][1] ;$dungeonFloor values may actually represent something other than floor (walls/black space/door), it would be more accurate the call it first layer (the only layer at this point)
Global $dungeonExplored[1][1] ;squares already seen are rememberd by the character, so theres a picture there according to the squares "floor" type (floor/wall/etc)
Global $dungeonMob[1][1] ;ids of mobs
Global $dungeonItems[1][1][20] ;to be implemented
Global $charpos[2] ;main chars xy
Global $images[3][100] ;collection of image paths used, 0 is black, 1 is default floor, 2 is default wall, 3 is our hero; needs to be split up to diffrent arrays for different types (floor/character/monster)
Global $monster, $floor ; values set by _getSquareType()
Global $mobs[100][10] ;identifiers of mobs, at each step they can move/hit in a random direction, [0][0] is their counter

;FileInstalls here
$maingui = GUICreate('game',900,550)
$textbox = GUICtrlCreateLabel("Welcome!",10,400,800,50)

$helpmenu = GUICtrlCreateMenu("Help")
$fileitem = GUICtrlCreateMenuItem("Info", $helpmenu)
GUICtrlSetState(-1, $GUI_DEFBUTTON)

$images[0][0]= @ScriptDir&"\Img\black.bmp"
$images[0][1]= @ScriptDir&"\Img\floor.bmp"
$images[0][2]= @ScriptDir&"\Img\wall.bmp"
$images[0][3]= @ScriptDir&"\Img\door.bmp"
$images[1][0]= @ScriptDir&"\Img\hero.bmp"
$images[1][1] = @ScriptDir&"\Img\mons1.bmp"
$images[1][2] = @ScriptDir&"\Img\mons2.bmp"
$images[2][1] = @ScriptDir&"\Img\lada1.bmp"
$images[2][2] = @ScriptDir&"\Img\címmerpajzs1.bmp"
_CreateLevel_Memory(50,20)
_CreateLevel_Gui(50, 20, 18, $maingui)
$label = GUICtrlCreateLabel("",0,360,900,30)
GUICtrlSetBkColor($label,0x050505)
GUISetState(@SW_SHOW)

while 1
Select
Case _IsPressed('0x57') Or _IsPressed('0x26')
_MoveCharacter(2)
sleep(50)
Case _IsPressed('0x41') Or _IsPressed('0x25')
_MoveCharacter(1)
sleep(50)
Case _IsPressed('0x53') Or _IsPressed('0x28')
_MoveCharacter(-2)
sleep(50)
Case _IsPressed('0x44') Or _IsPressed('0x27')
_MoveCharacter(-1)
sleep(50)
Case 1
sleep(100)
EndSelect
If GUIGetMsg()==-3 Then Exit
WEnd

Func _CreateLevel_Gui($x, $y, $size, $gui) ;visualization of the "dungeon" as a grid of pictures. Based on the Grid UDF made by Ichigo
If $x < 0 or $y < 0 or $size < 0 then Return -1
GUICtrlCreatePic($images[1][0], $charpos[0] * $size, $charpos[1] * $size, $size, $size)
ReDim $xGrid[$x][$y]
$bX = $x
$bY = $y

GUISwitch($gui)
For $x = 0 to $bX - 1
For $y = 0 to $bY - 1
if $dungeonExplored[$x][$y] = 0 then
$xGrid[$x][$y] = GUICtrlCreatePic($images[0][0], $x * $size, $y * $size, $size, $size) ;most of the place is black...
Else
$xGrid[$x][$y] = GUICtrlCreatePic($images[0][0], $x * $size, $y * $size, $size, $size) ;however, a few blocks are already "seen" by the mainchar at startup
_RenderGrid($x,$y)
EndIf
Next
Next

Return 1
EndFunc
Func _CreateLevel_Memory($sizex, $sizey) ;creating the floor and a little house/fort/whatever for the character to start in. Some algorith to generate a level goes here

ReDim $dungeonExplored[$sizex][$sizey]
ReDim $dungeonFloor[$sizex][$sizey]
ReDim $dungeonItems[$sizex][$sizey][20]
ReDim $dungeonMob[$sizex][$sizey]

$charpos[0] = 5 ;Random(1,10,1)
$charpos[1] = 1 ;Random(1,10,1)
_CreateRoom(0,0,10,10,0,5,5,0)
_CreateRoom(9,4,10,3,4,1,0,0) ;folyosó
_CreateRoom(9,6,8,9,4,0,4,0)
_CreateRoom(0,10,10,10,5,5,0,0)
_CreateRoom(9,14,10,3,0,1,4,0)
_CreateRoom(18,0,20,20,0,10,0,10) ;bigroom
_CreateRoom(25,8,5,5,0,2,0,2)
_CreateRoom(29,8,5,5,0,2,0,2)
_CreateRoom(33,8,5,5,0,2,0,2);kicsi
for $x=0 to $sizex -1
for $y=0 to $sizey -1
If $dungeonFloor[$x][$y] = 1 OR $dungeonFloor[$x][$y] = "" And 3 > Random(0,99,1) Then ;on each floor type square already set by_createRoom
$type = Random(1,2,1) ;3% chance for a random type monster to appear (only 2 types here)
_SpawnMob($x,$y,$type)
EndIf
if $dungeonFloor[$x][$y] = "" Then ;this is needed so the default squre type wont override rooms/corridors created before (not implemented yet)
$dungeonFloor[$x][$y] = 1 ;set everything to 1, walkable floor.
$dungeonExplored[$x][$y] = 0 ;nothing is explored yet
EndIf
Next
; MsgBox(0,"lol",$x &"x-y"&$y)
Next

For $x = -1 to 1
for $y = -1 to 1
$dungeonExplored[$charpos[0] + $x][$charpos[1] + $y] = 1 ;the squares next to the character start as explored
Next
Next
EndFunc

Func _SpawnMob($x,$y,$type)
$mobs[0][0] +=1
$dungeonMob[$x][$y] = $mobs[0][0]
$mobs[$mobs[0][0]][0] = $type ;type of the mob == number of the image that gets rendered
$mobs[$mobs[0][0]][1] = Random(1,3,1) ;hp 1-3
$mobs[$mobs[0][0]][2] = $x
$mobs[$mobs[0][0]][3] = $y
$loot1 = Random(1,2,1)
$mobs[$mobs[0][0]][4] = $loot1
$mobs[$mobs[0][0]][5] = ""
EndFunc

Func _KillMob($id)
$mobs[$id][0] = ""
$mobs[$id][1] = 0 ;hp
$dungeonMob[$mobs[$id][2]][$mobs[$id][3]] = ""
$dungeonItems[$mobs[$id][2]][$mobs[$id][3]][0] += 1
$itemnumber = $dungeonItems[$mobs[$id][2]][$mobs[$id][3]][0]
$dungeonItems[$mobs[$id][2]][$mobs[$id][3]][$itemnumber] = $mobs[$id][4]
$mobs[$id][2] = -1
$mobs[$id][3] = -1

EndFunc

Func _HitMob($id)
$mobs[$id][1] -= 1
If $mobs[$id][1] = 0 Then _KillMob($id)
EndFunc


Func _MobMove()
For $mob = 1 to $mobs[0][0]
$direction = Random(1,5,1)
$tempx = $mobs[$mob][2]
$tempy = $mobs[$mob][3]
If $tempx = -1 Then ContinueLoop ;halott szörnyek nem ugrálnak
Switch $direction
Case 1 ;"left"
$left = _getSquareType($mobs[$mob][2] - 1,$mobs[$mob][3])
If $left = -1 Then $direction = 3
If $left = 1 And $floor = 2 Then $direction = 3
If $left = 1 AND $floor = 1 Then $mobs[$mob][2] -= 1
If $left = 1 And $floor = 3 AND 101 > Random(1,100) Then _OpenDoor($mobs[$mob][2] - 1,$mobs[$mob][3])
If $left = 2 And $monster <> $mobs[$mob][0] Then _HitMob($monster)
Case 2; "right"
$right = _getSquareType($mobs[$mob][2] + 1,$mobs[$mob][3])
If $right = -1 Then $direction = 4
If $right = 1 And $floor = 2 Then $direction = 4
If $right = 1 AND $floor = 1 Then $mobs[$mob][2] += 1
If $right = 1 And $floor = 3 AND 101 > Random(1,100) Then _OpenDoor($mobs[$mob][2]+1,$mobs[$mob][3])
If $right = 2 And $monster <> $mobs[$mob][0] Then _HitMob($monster)
Case 3; "up"
$up = _getSquareType($mobs[$mob][2] ,$mobs[$mob][3]- 1)
If $up = -1 Then $direction = 4
If $up = 1 And $floor = 2 Then $direction = 4
If $up = 1 AND $floor = 1 Then $mobs[$mob][3] -= 1
If $up = 1 And $floor = 3 AND 101 > Random(1,100) Then _OpenDoor($mobs[$mob][2],$mobs[$mob][3] - 1)
If $up = 2 And $monster <> $mobs[$mob][0] Then _HitMob($monster)
Case 4; "down"
$down = _getSquareType($mobs[$mob][2],$mobs[$mob][3] + 1)
If $down = -1 Then $direction = 1
If $down = 1 And $floor = 2 Then $direction = 1
If $down = 1 AND $floor = 1 Then $mobs[$mob][3] += 1
If $down = 1 And $floor = 3 AND 101 > Random(1,100) Then _OpenDoor($mobs[$mob][2],$mobs[$mob][3]+1)
If $down = 2 And $monster <> $mobs[$mob][0] Then _HitMob($monster)
EndSwitch
;IF $
$dungeonMob[$tempx][$tempy] = ""
$dungeonMob[$mobs[$mob][2]][$mobs[$mob][3]] = $mob
Next
EndFunc

Func _CreateRoom($startx, $starty, $sizex , $sizey, $fal1 = 0,$fal2 = 0,$fal3 = 0,$fal4 = 0) ;creates a square room. last variable is the side of the room to have its door on
$sizex -= 1 ;room dimensions corretion, so _CreateRoom(10, 10, 4 , 4) is a 4x4 room rather then a 5x5
$sizey -= 1
$x = $startx
for $y=$starty to $sizey + $starty ;top wall
If $dungeonFloor[$x][$y] <> 3 Then
$dungeonFloor[$x][$y] = 2
$dungeonExplored[$x][$y] = 0
EndIf
Next
for $x = $startx + 1 to $sizex + $startx ; everything else, walls on the starting and ending position
$y=$starty
If $dungeonFloor[$x][$y] <> 3 Then
$dungeonFloor[$x][$y] = 2
$dungeonExplored[$x][$y] = 0
EndIf
for $y=$starty + 1 to $sizey + $starty
If $dungeonFloor[$x][$y] <> 3 Then
$dungeonFloor[$x][$y] = 1
$dungeonExplored[$x][$y] = 0
EndIf
Next
$y=$sizey + $starty
If $dungeonFloor[$x][$y] <> 3 Then
$dungeonFloor[$x][$y] = 2
$dungeonExplored[$x][$y] = 0
EndIf
Next
$x = $startx + $sizex
for $y=$starty to $sizey + $starty ;bottom wall
If $dungeonFloor[$x][$y] <> 3 Then
$dungeonFloor[$x][$y] = 2
$dungeonExplored[$x][$y] = 0
EndIf
Next
If $fal1 > 0 Then ;if top wall
$hol = $fal1
If $dungeonFloor[$startx+ $hol][$starty] <> 1 Then
$dungeonFloor[$startx+ $hol][$starty] = 3
EndIf
EndIf
If $fal2 > 0 Then ;if right wall
$hol = $fal2
If $dungeonFloor[$startx + $sizex][$starty+ $hol] <> 1 Then
$dungeonFloor[$startx + $sizex][$starty+ $hol] = 3
EndIf
EndIf
If $fal3 > 0 Then ;if bottom wall
$hol = $fal3
If $dungeonFloor[$startx + $hol][$starty+ $sizey] <> 1 Then
$dungeonFloor[$startx+ $hol][$starty + $sizey] = 3
EndIf
EndIf
If $fal4 > 0 Then;if left wall
$hol = $fal4
If $dungeonFloor[$startx][$starty+ $hol] <> 1 Then
$dungeonFloor[$startx][$starty+ $hol] = 3
EndIf
EndIf
EndFunc

Func _MoveCharacter($direction) ;Character tries to go in a certain direction. To do: split up to more functions, so other objects (monsters?) may access those functions
$temp = $xGrid[$charpos[0]][$charpos[1]] ;point where he tries to move from
If Abs($direction) == 1 Then
$dir = _getSquareType($charpos[0] - $direction,$charpos[1])
If $dir = 1 AND $floor = 1 Then $charpos[0] -= $direction
If $dir = 1 And $floor = 3 Then _OpenDoor($charpos[0] - $direction,$charpos[1])
Else
$dir = _getSquareType($charpos[0] ,$charpos[1]- ($direction/2))
If $dir = 1 AND $floor = 1 Then $charpos[1] -= ($direction/2)
If $dir = 1 And $floor = 3 Then _OpenDoor($charpos[0],$charpos[1] - ($direction/2))
EndIf
If $dir = -1 Then Return 0
If $dir = 1 And $floor = 2 Then return 0
If $dir = 2 Then _HitMob($monster)
_MobMove()
If Abs($direction)==2 Then
For $x = -3 to 3
_RenderGrid($charpos[0]+$x,$charpos[1]+2*$direction, 3)
Next
Else 
For $x = -3 to 3
_RenderGrid($charpos[0]+4*$direction,$charpos[1]+$x, 3)
Next
EndIf
For $y = -3 to 3 ;render your new surroundings: set those squres to explored, and show their picture accoring to "floor" value
for $x = -3 to 3
_RenderGrid($charpos[0]-$x,$charpos[1]-$y)
Next
Next

EndFunc

Func _getSquareType($x,$y) ;sets $floor to floor type and returns 1, or returns 2 and sets $monster id if a monster is there
If $y >= 0 And $x >=0 AND $x < UBound($xGrid,1) AND $y < UBound($xGrid,2) Then
If ($x = $charpos[0] AND $y = $charpos[1]) Then
Return 0
ElseIf ($dungeonMob[$x][$y] <> "") Then
$monster = $dungeonMob[$x][$y]
Return 2
EndIf
$floor = $dungeonFloor[$x][$y]
return 1
Else
Return -1
EndIf
EndFunc

Func _RenderGrid($x,$y,$exclude = "")
If $y >= 0 And $x >=0 AND $x < UBound($xGrid,1) AND $y < UBound($xGrid,2) Then ;errors avoided
$img_f = $dungeonFloor[$x][$y]
$img_i = $dungeonItems[$x][$y][0]
$img_m = $dungeonMob[$x][$y]
If $exclude = 1 Then $img_f = ""
If $exclude = 2 Then $img_i = 0
If $exclude = 3 Then $img_m = ""
If ($x = $charpos[0] And $y = $charpos[1]) Then
GUICtrlSetImage($xGrid[$x][$y], $images[1][0])
ElseIf $img_m <> "" Then
$img_m = $mobs[$img_m][0]
GUICtrlSetImage($xGrid[$x][$y], $images[1][$img_m])
ElseIf $dungeonExplored[$x][$y]<>0 Then
If $img_i <> 0 Then
$img_i = $dungeonItems[$x][$y][$img_i]
GUICtrlSetImage($xGrid[$x][$y], $images[2][$img_i])
Else
GUICtrlSetImage($xGrid[$x][$y], $images[0][$img_f])
EndIf
EndIf
If $dungeonExplored[$x][$y]=0 Then $dungeonExplored[$x][$y]=1
Else
return 0
EndIf
EndFunc


Func _OpenDoor($bX,$bY)
$kocka = Random(0,100,1) ;d100 dice to get success of door "opening" (right now: smashing)
If Random(0,100,1)<=75 Then Return 0 ; 3 out of 4, you fail
$dungeonFloor[$bX][$bY] = 1 ;the door there is now a floor
Return 2 ;you smash the door
EndFunc

Func _IsPressed($hexKey)
Local $aR = DllCall("user32", "int", "GetAsyncKeyState", "int", $hexKey)
If Not @error And BitAND($aR[0], 0x8000) = 0x8000 Then Return 1
Return 0
EndFunc

_________[u]UDFs[/u]_________-Mouse UDF-Math UDF-Misc Constants-Uninstaller Shell

Share this post


Link to post
Share on other sites

Thanks for your reply! Altough meanwhile a found that storing the value of the currently shown picture for each grid, and checking that before changing pictures to see if its the same is actually way faster than my current method, contrary to what i said in my first post here... Now im trying to make him not to see through walls, and it already works, but it still makes it see around the corner sometimes.

Share this post


Link to post
Share on other sites

That is true (and to an extent I had done that in the modified version I posted), but also look at the changes to _MoveCharacter, _getSquareType, _OpenDoor, _IsPressed, and your primary loop. These also provide some performance boost.

You should probably look into doing something like what I did to _MoveCharacter to your _MobMove function. Like...

Func _MobMove()
For $mob = 1 to $mobs[0][0]
$direction = Random(-2,2,1)
$tempx = $mobs[$mob][2]
$tempy = $mobs[$mob][3]
If $tempx = -1 Then ContinueLoop ;halott szörnyek nem ugrálnak
If Abs($direction) == 1 Then
    $dir = _getSquareType($mobs[$mob][2] - $direction,$mobs[$mob][3])
    If $dir = -1 Then $direction = 3
    If $dir = 1 And $floor = 2 Then $direction = 3
    If $dir = 1 AND $floor = 1 Then $mobs[$mob][2] -= $direction
    If $dir = 1 And $floor = 3 AND 101 > Random(1,100) Then _OpenDoor($mobs[$mob][2] - $direction,$mobs[$mob][3])
    If $dir = 2 And $monster <> $mobs[$mob][0] Then _HitMob($monster)
ElseIf Abs($direction) == 2 Then
    $dir = _getSquareType($mobs[$mob][2] ,$mobs[$mob][3]- $direction/2)
    If $dir = -1 Then $direction = 4
    If $dir = 1 And $floor = 2 Then $direction = 4
    If $dir = 1 AND $floor = 1 Then $mobs[$mob][3] -= $direction/2
    If $dir = 1 And $floor = 3 AND 101 > Random(1,100) Then _OpenDoor($mobs[$mob][2],$mobs[$mob][3] - $direction/2)
    If $dir = 2 And $monster <> $mobs[$mob][0] Then _HitMob($monster)
EndIf
$dungeonMob[$tempx][$tempy] = ""
$dungeonMob[$mobs[$mob][2]][$mobs[$mob][3]] = $mob
Next
EndFuncoÝ÷ Ù.².Û¶Ø^¦¸¨®+r¡ûazÊ®j·¬¶Þ¦ºzËv)Ì¢÷ªÚr׫²ç!¶­¶²j·©®²Ç{azƦzø¬¹©]·¶*'jËazZÉêâ²j/x+­æ­zÆ¥j¸¾+.jZ^­ú+©Üyº(²Ö®¶­sdb'2b33c¶F&V7FöâÓÓFVà f÷"b33c·ÒÓ2Fò0 f÷"b33c·ÒÓ2Fò0 õ&VæFW$w&Bb33c¶6'÷5³ÒÒb33c·Âb33c¶6'÷5³ÒÒb33c· æW@ æW@¤VÇ6P f÷"b33c·ÒÓ2Fò0 f÷"b33c·ÒÓ2Fò0 õ&VæFW$w&Bb33c¶6'÷5³ÒÒb33c·Âb33c¶6'÷5³ÒÒb33c· æW@ æW@¤VæDoÝ÷ Ø l w«z+²X Ùr}«-z°«y«^F&jëh×6Func _CreateRoom($startx, $starty, $sizex , $sizey, $fal1 = 0,$fal2 = 0,$fal3 = 0,$fal4 = 0) ;creates a square room. last variable is the side of the room to have its door on
    $sizex -= 1 ;room dimensions corretion, so _CreateRoom(10, 10, 4 , 4) is a 4x4 room rather then a 5x5
    $sizey -= 1
    for $x = $startx + 1 to $sizex + $startx ; everything else, walls on the starting and ending position
        $y=$starty
        If $dungeonFloor[$x][$y] <> 3 Then
        $dungeonFloor[$x][$y] = 2
        $dungeonExplored[$x][$y] = 0
        EndIf
        for $y=$starty + 1 to $sizey + $starty
            If $dungeonFloor[$x][$y] <> 3 Then
            $dungeonFloor[$x][$y] = 1
            $dungeonExplored[$x][$y] = 0
            EndIf
        Next
        $y=$sizey + $starty
        If $dungeonFloor[$x][$y] <> 3 Then
        $dungeonFloor[$x][$y] = 2
        $dungeonExplored[$x][$y] = 0
        EndIf
    Next
    $x = $startx
    $x2 = $x + $sizex
    for $y=$starty to $sizey + $starty ;top wall
        If $dungeonFloor[$x][$y] <> 3 Then
            $dungeonFloor[$x][$y] = 2
            $dungeonExplored[$x][$y] = 0
        EndIf
        If $dungeonFloor[$x2][$y] <> 3 Then
            $dungeonFloor[$x2][$y] = 2
            $dungeonExplored[$x2][$y] = 0
        EndIf
    Next
    If ($fal1 > 0 And $dungeonFloor[$startx+ $fal1][$starty] <> 1) Then ;if top wall
        $dungeonFloor[$startx+ $fal1][$starty] = 3
    EndIf
    If ($fal2 > 0 And $dungeonFloor[$startx + $sizex][$starty+ $fal2] <> 1) Then ;if right wall
        $dungeonFloor[$startx + $sizex][$starty+ $fal2] = 3
    EndIf
    If ($fal3 > 0 And $dungeonFloor[$startx + $fal3][$starty+ $sizey] <> 1) Then ;if bottom wall
        $dungeonFloor[$startx+ $fal3][$starty + $sizey] = 3
    EndIf
    If ($fal4 > 0 And $dungeonFloor[$startx][$starty+ $fal4] <> 1) Then;if left wall
        $dungeonFloor[$startx][$starty+ $fal4] = 3
    EndIf
EndFunc

_________[u]UDFs[/u]_________-Mouse UDF-Math UDF-Misc Constants-Uninstaller Shell

Share this post


Link to post
Share on other sites

Quick opt in _OpenDoor:

Func _OpenDoor($bX,$bY)
If Random(1,4,1)=4 Then $dungeonFloor[$bX][$bY] = 1
EndFuncoÝ÷ Ù¢rJ))È°úÞ²Çjëh×6Func _IsPressed($hexKey)
Local $aR = DllCall("user32", "int", "GetAsyncKeyState", "int", $hexKey)
Return (Not @error And BitAND($aR[0], 0x8000) = 0x8000)
EndFunc

You may also want to try fixing the bug shown in the attached picture.

Can you post the latest copy?

post-29053-1232386899_thumb.jpg


_________[u]UDFs[/u]_________-Mouse UDF-Math UDF-Misc Constants-Uninstaller Shell

Share this post


Link to post
Share on other sites

_createroom is a lot more readable and consisten your way. I like charmove and mobmove, but for now i wont change it, so i can see trough it, and add things, and not confuse left with right, etc. Last time i didnt have much time to read your modified code, sorry for that. Now i read it more carefully, but didn't manage to find the part i talked about in my second post. What i did was to add a new array for the _RenderGrid to use:

Func _RenderGrid($x,$y,$exclude = "")
If $y >= 0 And $x >=0 AND $x < UBound($xGrid,1) AND $y < UBound($xGrid,2) Then ;errors avoided
$img_f = $dungeonFloor[$x][$y]
$img_i = $dungeonItems[$x][$y][0]
$img_m = $dungeonMob[$x][$y]
If $exclude = 1 Then $img_f = ""
If $exclude = 2 Then $img_i = 0
If $exclude = 3 Then $img_m = ""
    Select
        case $x = $charpos[0] And $y = $charpos[1]
            IF  $shownimage[$x][$y][0] = 1 And  $shownimage[$x][$y][1] = 0 Then Return 0
            GUICtrlSetImage($xGrid[$x][$y], $images[1][0])
            $shownimage[$x][$y][0] = 1
            $shownimage[$x][$y][1] = 0
            $seen[$x][$y]=1
            $dungeonExplored[$x][$y]=1
        case $img_m <> ""
            $img_m = $mobs[$img_m][0]
            If $shownimage[$x][$y][0] = 1 and $shownimage[$x][$y][1] = $img_m then Return 0
            GUICtrlSetImage($xGrid[$x][$y], $images[1][$img_m])
            $shownimage[$x][$y][0] = 1
            $shownimage[$x][$y][1] = $img_m
            $seen[$x][$y]=1
            $dungeonExplored[$x][$y]=1
        case $img_i <> 0
            $img_i = $dungeonItems[$x][$y][$img_i]
             If $shownimage[$x][$y][0] = 2 and $shownimage[$x][$y][1] = $img_i then Return 0
            GUICtrlSetImage($xGrid[$x][$y], $images[2][$img_i])
            $shownimage[$x][$y][0] = 2
            $shownimage[$x][$y][1] = $img_i
            $seen[$x][$y]=1 
            $dungeonExplored[$x][$y]=1
        case $img_f <> ""
            If $shownimage[$x][$y][0] = 0 and $shownimage[$x][$y][1] = $img_f then Return 0
            GUICtrlSetImage($xGrid[$x][$y], $images[0][$img_f])
            $shownimage[$x][$y][0] = 0
            $shownimage[$x][$y][1] = $img_f
            $seen[$x][$y]=1
            $dungeonExplored[$x][$y]=1
    EndSelect
Else
return 0
EndIf
EndFuncoÝ÷ Ù8^²v)©®ÞéíiÈb½ç[ÊØb²+&¹Èf¢·¬    â~'Ûaz{azaz»ax,jÁ +k'­"f z+,½éߢ¹²^®w(­z´áȬ¦ºi¹r²Ø¥Ë¢b©[ºÛayÈZ­§-z¸¬i¹^¶¨½ì"¶tú
âwûr·§uêâ¯z¼­)à{azèqë,:Ø^®Øb"§^jëh×6Func _RenderRay($x,$y,$level,$dirx,$diry)
    _RenderGrid($x,$y)
    if $y+$diry >= 0 And $y+$diry >=0 AND $x+$dirx < UBound($xGrid,1) AND $y+$diry < UBound($xGrid,2) AND $dungeonFloor[$x][$y] = 1 Then
    _RenderRay($x+$dirx,$y+$diry,$level,$dirx,$diry)
    EndIf
EndFunc
Func _RenderParent($x,$y,$level,$dirx,$diry)
    _RenderGrid($x,$y)
    if $dungeonFloor[$x][$y] = 1 Then
    _RenderParent($x + $dirx ,$y +$diry,$level,$dirx,$diry)
    _RenderRay($x,$y,$level,$dirx,0)
    _RenderRay($x,$y,$level,0,$diry)
    EndIf
EndFunc
Func _RenderCharSur($x ,$y)
    _RenderRay($x,$y,0,1,0)
    _RenderRay($x,$y,0,0,1)
    _RenderRay($x,$y,0,0,-1)
    _RenderRay($x,$y,0,-1,0)
    _RenderParent($x+1,$y+1,0,1,1)
    _RenderParent($x-1,$y+1,0,-1,1)
    _RenderParent($x+1,$y-1,0,1,-1)
    _RenderParent($x-1,$y-1,0,-1,-1)

EndFunc

_rendercharsur is used after each step made. It wont render things behind a wall (exepct when it does:P), but it makes me see around the corner. Its kinda lame, but i coulnt come up with anything better. I started looking for some algorithm to do this better and found this: http://roguebasin.roguelikedevelopment.org...e_shadowcasting

...and other methods too, but this one seems to be the best. The only simmilarity with my method is the recursiveness, so i cant really use any of the above. I'd need to make a monster-de-render, witch would probably work the same way for my current basic renderer, and this fancy shadowcasting thing, so ill start working on that... once i finish with my exams.

Share this post


Link to post
Share on other sites

The open door structure is that way, because i wanted it to resemble dice rolls, but your right it is a bit silly like that.

Share this post


Link to post
Share on other sites

_createroom is a lot more readable and consisten your way. I like charmove and mobmove, but for now i wont change it, so i can see trough it, and add things, and not confuse left with right, etc. Last time i didnt have much time to read your modified code, sorry for that. Now i read it more carefully, but didn't manage to find the part i talked about in my second post. What i did was to add a new array for the _RenderGrid to use:

Thanks :)

All it did was check the $dungeonExplored array for the items and floor, if it was explored it just passed over that area, it was more simplistic, but it does most of the task accomplished by your function.

I will now take a look at your latest version.


_________[u]UDFs[/u]_________-Mouse UDF-Math UDF-Misc Constants-Uninstaller Shell

Share this post


Link to post
Share on other sites

Taking a quick look, I see that you have changed over from _IsPressed to HotKeySet, this causes choppy and unpredictable movement depending on the key-repeat settings on the person's computer. I HIGHLY recommend switching back to _IsPressed.

Also, you can make the exit button work by changing your main loop to be: while GUIGetMsg()<>-3

Whatever you have done to the display function introduces a bug where the person can see multiple copies of a monster or (in only one case that I saw), 2 copies of themself.


_________[u]UDFs[/u]_________-Mouse UDF-Math UDF-Misc Constants-Uninstaller Shell

Share this post


Link to post
Share on other sites

Taking a quick look, I see that you have changed over from _IsPressed to HotKeySet, this causes choppy and unpredictable movement depending on the key-repeat settings on the person's computer. I HIGHLY recommend switching back to _IsPressed.

Also, you can make the exit button work by changing your main loop to be: while GUIGetMsg()<>-3

Whatever you have done to the display function introduces a bug where the person can see multiple copies of a monster or (in only one case that I saw), 2 copies of themself.

I commented out the ispressed part and changed back to hotkeys for testing reasons, it can move faster this way, and can check out the whole area faster.

Monster being duplicated is caused because the de-render i used before wont work here, i cannot exactly tell whitch squares were rendered before the last step. Thats why i aded a $seen array. It is not functional yet, now identical to $dungeonexplored, but will be used to check the grid for monsters that were seen before.

One sec and ill fix this (i hope).

Thanks for the guimsg hint, ill put it in right now :)

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0