mvendak Posted January 17, 2009 Share Posted January 17, 2009 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 Link to comment Share on other sites More sharing options...
NerdFencer Posted January 19, 2009 Share Posted January 19, 2009 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... expandcollapse popup#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 Link to comment Share on other sites More sharing options...
mvendak Posted January 19, 2009 Author Share Posted January 19, 2009 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. Link to comment Share on other sites More sharing options...
NerdFencer Posted January 19, 2009 Share Posted January 19, 2009 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... expandcollapse popupFunc _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 Link to comment Share on other sites More sharing options...
NerdFencer Posted January 19, 2009 Share Posted January 19, 2009 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? _________[u]UDFs[/u]_________-Mouse UDF-Math UDF-Misc Constants-Uninstaller Shell Link to comment Share on other sites More sharing options...
mvendak Posted January 19, 2009 Author Share Posted January 19, 2009 _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:expandcollapse popupFunc _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. Link to comment Share on other sites More sharing options...
mvendak Posted January 19, 2009 Author Share Posted January 19, 2009 Last version: dungeon3_t.au3 Link to comment Share on other sites More sharing options...
mvendak Posted January 19, 2009 Author Share Posted January 19, 2009 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. Link to comment Share on other sites More sharing options...
NerdFencer Posted January 19, 2009 Share Posted January 19, 2009 _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 Link to comment Share on other sites More sharing options...
NerdFencer Posted January 19, 2009 Share Posted January 19, 2009 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 Link to comment Share on other sites More sharing options...
mvendak Posted January 19, 2009 Author Share Posted January 19, 2009 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()<>-3Whatever 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 Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now