I saw this enemy in a platformer game and thought it would be nice to make myself. I tried it 8 months ago and failed but today I figured out what I did wrong. (You can re-use the wallcrawler class)
Import mojo Const tilewidth = 32 Const tileheight = 32 Const mapwidth:Int=20 Const mapheight:Int=10 Global map:Int[][] = [ [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1], [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1], [1,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,1], [1,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,1], [1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,1], [1,0,0,0,0,0,1,1,1,0,0,0,1,1,0,0,0,0,0,1], [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1], [1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1], [1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1], [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1] ] Class wallcrawler 'x and y tilepositions(cells) Field x:Float,y:Float 'nx and ny is next tileposition Field nx:Int,ny:Int 'offset for drawing (smooth movement) Field offx:Int,offy:Int ' direction wallcrawler is goint to ' 1 = up, 2 = right, 3 = down, 4 = left Field direction:Int Method New(x:Float,y:Float) Self.x = x Self.y = y Self.nx = x Self.ny = y 'start going right Self.direction = 2 End Method Method update() If x = nx And y = ny Else ' if not on next position then slowly move there If x<nx Then offx+=1 If x>nx Then offx-=1 If y<ny Then offy+=1 If y>ny Then offy-=1 If offx>tilewidth Then x+=1;offx=0 If offx<-tilewidth Then x-=1;offx=0 If offy>tileheight Then y+=1;offy=0 If offy<-tileheight Then y-=1;offy=0 Return End If ' get the next directions Local rightd:Int=direction+1 Local forwardd:Int=direction Local leftd:Int=direction-1 ' b sure to stay in legal movement If rightd > 4 Then rightd = 1 If leftd < 1 Then leftd = 4 ' first see if we can go right If postaken(rightd) = True direction = rightd movepos(rightd) Return End If ' then see if we can go forward If postaken(forwardd) = True direction = forwardd movepos(forwardd) Return End If 'then see if we can go left If postaken(leftd) = True direction = leftd movepos(leftd) Return End If End Method ' get next cell position Method movepos(d:Int) nx = x ny = y Select d Case 1;ny-=1 Case 2;nx+=1 Case 3;ny+=1 Case 4;nx-=1 End Select End Method 'see if the next possible position if a wall Method postaken(d:Int) Select d Case 1;If map[y-1][x] = 0 Then Return True Case 2;If map[y][x+1] = 0 Then Return True Case 3;If map[y+1][x] = 0 Then Return True Case 4;If map[y][x-1] = 0 Then Return True End Select Return False End Method Method draw() SetColor 255,0,0 DrawRect x*tilewidth+offx,y*tileheight+offy,tilewidth,tileheight End Method End Class Class players Field x:Float = 640/2-16 Field y:Float = 480/2 Field pw:Int=32 Field ph:Int=32 Field incy:Float Field jump:Bool=False Method New() End Method Method update() playermovement playergravity End Method Method playergravity() ' If the player is on the ground and the space bar is pressed If jump = False And playertc(0,1) = False jump = True incy = 0 End If If jump = False And KeyDown(KEY_SPACE) = True incy = -4 jump = True End 'If the player is in the jump If jump = True incy += 0.1 'if the player is going up If incy <=0 For Local i:Int = 0 Until Abs(incy) y -= 1 If playertc(0,-1) = True incy = 0 Exit End If End End ' if the player if going down If incy > 0 For Local i:Int = 0 Until incy y += 1 'if the player touches the ground If playertc(0,1) = True jump = False Exit End End End End End Method Method playermovement() If KeyDown(KEY_RIGHT) For Local i=0 Until 2 If playertc(1,0) = False x+=1 End If Next End If If KeyDown(KEY_LEFT) For Local i=0 Until 2 If playertc(-1,0) = False x-=1 End If Next End If End Method Method playertc:Bool(x1:Int,y1:Int) Local cx = (x + x1) / tilewidth Local cy = (y + y1) / tileheight For Local y2=cy-1 Until cy+2 For Local x2=cx-1 Until cx+2 If x2>=0 And x2<mapwidth And y2>=0 And y2<mapheight If map[y2][x2] > 0 If rectsoverlap(x+x1,y+y1,pw,ph,x2*tilewidth, y2*tileheight,tilewidth,tileheight) = True Return True End If End If End If Next Next Return False End Method Method draw() ' draw the player SetColor 255,255,0 DrawOval x,y,pw,ph End Method End Class Global player:List<players> = New List<players> Global wallcrawlers:List<wallcrawler> = New List<wallcrawler> Class MyGame Extends App Method OnCreate() SetUpdateRate(60) player.AddLast(New players()) createwallcrawlers End Method OnUpdate() ' Player left and right movement For Local i:=Eachin player i.update Next For Local i:=Eachin wallcrawlers i.update Next End Method OnRender() Cls(0,0,0) SetColor(255,255,255) ' draw the map For Local y:Int = 0 Until mapheight For Local x:Int = 0 Until mapwidth If map[y][x] = 1 Then DrawRect(x*tilewidth,y*tileheight,tilewidth,tileheight) End End DrawText "Platformer Example with Wallcrawlers(wall following)",10,10 DrawText "Use cursor left/right and space bar to move player",160,10 For Local i:=Eachin player i.draw Next For Local i:=Eachin wallcrawlers i.draw Next End End Function createwallcrawlers:Void() For Local y=0 Until mapheight For Local x=0 Until mapwidth If map[y][x] = 2 map[y][x] = 0 wallcrawlers.AddLast(New wallcrawler(x,y)) End If Next Next End Function Function rectsoverlap:Bool(x1:Int, y1:Int, w1:Int, h1:Int, x2:Int, y2:Int, w2:Int, h2:Int) If x1 >= (x2 + w2) Or (x1 + w1) <= x2 Then Return False If y1 >= (y2 + h2) Or (y1 + h1) <= y2 Then Return False Return True End Function Main() New MyGame() End
No comments:
Post a Comment
Note: Only a member of this blog may post a comment.