(Updated 03/05/2017 with improved source code and new video)
A little update to older post. As the title of the post says we’re making a worm game (in Monkey X). In this version the worm is controlled by touching the screen keeping in mind that the game is really aimed to Android.
I’ll explain here how the worm is controlled.
If you move your finger ”up” from the worm’s head, the worm goes to that direction and respectively to other directions.
See the video below:
The direction is determined by comparing two subsequent update rounds’ TouchX() and TouchY() coordinates.
The test can’t be straightforward TouchX() or TouchY() test, because the player probably won’t move his/her finger absolutely to one of the four directions the worm is to be controlled.
This is why there is another test in controlling the worm: The absolute values of difference of the two subsequent update round’s TouchX() and TouchY() coordinates. If the player wants to control the worm ”up”, the player probably has moved his/her finger more vertically than horizontally.
See the source code:
Import mojo Function Main:Int() New MyApp Return 0 End Class MyApp Extends App Const STARTSCREEN = 0 Const PLAY = 1 Field gfxBG:Image Const BG_WIDTH:Int = 640 Const BG_HEIGHT:Int = 480 Field devWidth:Float, devHeight:Float, scaleX:Float, scaleY:Float Global wormLength:Int = 8 Global wormX:Int[wormLength * 17], wormY:Int[wormLength * 17] Field dx, dy:Int Field foodX:Int, foodY:Int Field drawFood:Bool Field gameState:Int Field touchX:Float, touchY:Float Field prevTX:Float, prevTY:Float Field prevHorChange:Float, prevVerChange:Float Method OnCreate() gfxBG = LoadImage("bg.png") devWidth = DeviceWidth() devHeight = DeviceHeight() scaleX = devWidth / BG_WIDTH scaleY = devHeight / BG_HEIGHT ' Init worm For Local w:Int = 0 To 7 * 17 wormX[w] = 200-w wormY[w] = 10*17 Next dx = 1 dy = 0 drawFood = True SetUpdateRate(60) End Method OnUpdate() If TouchHit(0) > 0 Then gameState = PLAY If gameState = STARTSCREEN Then Return If TouchDown() > 0 Then touchX = TouchX() / scaleX touchY = TouchY() / scaleY ' Calculate the differences between current and previous update rounds' touch values If prevTX < touchX Then prevHorChange = Abs(prevTX - touchX) Else prevHorChange = Abs(touchX - prevTX) If prevTY < touchY Then prevVerChange = Abs(prevTY - touchY) Else prevVerChange = Abs(touchY - prevTY) ' Up If touchY - prevTY < 0 And Abs(touchY - prevTY) > prevHorChange Then dx = 0 dy = -1 Endif ' Down If touchY - prevTY > 0 And Abs(prevTY - touchY) > prevHorChange Then dx = 0 dy = 1 Endif ' Left If touchX - prevTX < 0 And Abs(touchX - prevTX) > prevVerChange Then dx = -1 dy = 0 Endif ' Right If touchX - prevTX > 0 And Abs(prevTX - touchX) > prevVerChange Then dx = 1 dy = 0 Endif prevTX = touchX prevTY = touchY Endif If drawFood = True Then foodX = Rnd()*(639-17) foodY = Rnd()*(479-17) drawFood = False Endif If Abs(wormX - foodX) < 17 And Abs(wormY - foodY) < 17 Then wormLength = wormLength + 1 ' Dynamically resize the arrays wormX = wormX.Resize(wormLength * 17) wormY = wormY.Resize(wormLength * 17) wormX[(wormLength-1)*17] = wormX[(wormLength-2)*17] wormY[(wormLength-1)*17] = wormY[(wormLength-2)*17] drawFood = True Endif For Local w:Int = (wormLength - 1) * 17 To 1 Step -1 wormX[w] = wormX[w-1] wormY[w] = wormY[w-1] Next wormX = wormX + dx wormY = wormY + dy End Method OnRender() ' Scale the graphics PushMatrix() Scale (scaleX,scaleY) DrawImage gfxBG,0,0 Select gameState Case STARTSCREEN SetColor 180,120,180 SetBlend AdditiveBlend DrawText "Simple worm game",(640 - TextWidth("Simple worm game")) / 2,10 DrawText "Move your finger on the screen to control the worm",(640 - TextWidth("Move your finger on the screen to control the worm")) / 2,40 DrawText "Touch anywhere to start",(640 - TextWidth("Touch anywhere to start")) / 2,70 Case PLAY SetColor 180,120,180 SetBlend AdditiveBlend DrawText "Worm Length: " + wormLength,0,0 SetColor 0,255,0 SetBlend AlphaBlend SetAlpha 1 SetColor 0,255,0 For Local w:Int = 0 To wormLength - 1 DrawOval wormX[w * 17],wormY[w * 17],17,17 Next SetColor 255,0,0 DrawOval wormX,wormY,17,17 SetColor 255,255,0 DrawOval foodX,foodY,17,17 End Select PopMatrix() End End Class
Source code license: Public domain.
Notice, that in this code one part of the worm’s “body” is 17 x 17 pixels, but the worm moves with step of one pixel and can be controlled with accuracy of one pixel. The example code above is simple implementation of this kind of worm game. The down side of the code is, that the sizes of the arrays for x– and y-coordinates depend of the length of the worm in pixels.
I may come back later with some implementation with different concept of moving the worm of which “body” is built with “blocks” of different size than one pixel, but the worm is controlled with accuracy of one pixel, without using arrays of which lengths depend on the size of the worm in pixels.