Created
September 8, 2013 18:58
-
-
Save Westenburg/6487451 to your computer and use it in GitHub Desktop.
A step by step tutorial for a Snake game in Codea. Aimed at absolute beginners (though would recommend starting with the Noob Lander tutorial first). Each step is commented and in its own separate tab- move the tab you wish to run to the far right
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--# Main | |
-- Snake tutorial | |
-- by West | |
--Graphics used are those supplied with Codea, particularly those of Kenney.nl and twolivesleft.com | |
-- This is a very simple example snake game. It is intended for use as an introduction into creating your second game in codea and is aimed at absolute beginners. Try the lander tutorial before this one | |
--ONLY THE FURTHEST RIGHT HAND TAB WILL BE EXECUTED. DRAG THE TAB FOR THE STEP YOU WISH TO RUN TO THE FAR RIGHT THEN PRESS RUN | |
--The following steps build up the game tab by tab | |
--1. Place a sprite on the screen | |
--2. Add x and y variables to control the position | |
--3. Rotate the sprite | |
--4. Add a variable, angle, to control the rotation of the sprite | |
--5. Control rotation through screen tapping. Also restrict the game to landscape only | |
--6. More advanced control to allow rotation in both directions | |
--7. Add a variable turning to control the rate of turning | |
--8. Add movement | |
--9. Add a body part | |
--10. Add a delay to the position of the body part | |
--11. Add a second body part | |
--12. Add a third body part | |
--13. Handle body parts as a loop | |
--14. Reverse the loop to draw from the tail forward | |
--15. Create "edible" mushrooms at a random screen position | |
--16. Add collision detection to allow the mushrooms to be picked up. Start with a smaller snake (5) and each mushroom will make the snake longer. Make the snake turn tighter by increasing the turning value | |
--17. Add collision detection with itself and the walls | |
--END OF TUTORIAL BUT NOT END OF THE GAME. The rest is up to you. Some general stuff, such as controlling the states of the game through a finite state machine are covered in the lunar lander tutorial. | |
--Some suggestions/challenges. Some are straightforward, others not so. | |
--1. Add in a finite state machine to control the win/lose/restart/menu screens and functions (see lunar lander) | |
--2. Add sound effects (see lunar lander) | |
--3. Add in a score system | |
--4. Make the snake faster (watch! simply adjusting the speed variable will cause the snake to stretch out - do you know why and how to stop it from happening?) | |
--5. Add in random bonuses (speed up, increase turning, decrease turning, reverse controls, add two body segments instead of 1, double snake size!, shrink back to orginal size,...) | |
--6. Add in walls. First round the edges, but then to form a non-rectangle arena - perhaps have a block in the centre? Moving walls? | |
--7. Add different levels, perhaps with an objective to complete each level (say collect 20 mushrooms, survive for 180s, avoid mushrooms for a minute) | |
--8. As the game progreses spawn more mushrooms at once | |
--9. Add a pretty background | |
--10. Customise the graphices | |
--11. Add an enemy snake! | |
--12. Use your imagination to create whatever you want! | |
function setup() | |
displayMode(FULLSCREEN) | |
supportedOrientations(LANDSCAPE_ANY) | |
saveProjectInfo("Description", "Step by step tutorial for writing a Snake game") | |
saveProjectInfo("Author", "Graeme West") | |
x=300 | |
y=500 | |
angle=90 | |
turning=4 | |
speed=2.5 | |
body={} | |
numBodyParts=5 | |
mushx=50+math.random(WIDTH-100) | |
mushy=50+math.random(HEIGHT-100) | |
end | |
function draw() | |
background(40, 40, 50) | |
if CurrentTouch.state==BEGAN or CurrentTouch.state==MOVING then | |
if CurrentTouch.x<WIDTH/2 then | |
angle = angle + turning | |
else | |
angle = angle - turning | |
end | |
end | |
x = x + speed*math.sin(math.rad(-angle)) | |
y = y + speed*math.cos(math.rad(-angle)) | |
sprite("Platformer Art:Mushroom",mushx,mushy) | |
if math.abs(x-mushx)<40 and math.abs(y-mushy)<40 then | |
numBodyParts = numBodyParts + 1 | |
mushx=50+math.random(WIDTH-100) | |
mushy=50+math.random(HEIGHT-100) | |
end | |
if x<0 or x>WIDTH or y<0 or y>HEIGHT then | |
background(math.random(255),math.random(255),math.random(255)) | |
end | |
for i=4,numBodyParts do | |
local reqFrame=4+(i*8) | |
if #body>reqFrame and math.abs(x-body[reqFrame].prevx)<25 and math.abs(y-body[reqFrame].prevy)<25 then | |
background(math.random(255),math.random(255),math.random(255)) | |
end | |
end | |
for i=numBodyParts,1,-1 do | |
local reqFrame=4+(i*8) | |
if #body>reqFrame then | |
pushMatrix() | |
translate(body[reqFrame].prevx,body[reqFrame].prevy) | |
rotate(body[reqFrame].prevangle) | |
sprite("Space Art:Part Green Hull 5",0,0) | |
popMatrix() | |
end | |
end | |
pushMatrix() | |
translate(x,y) | |
rotate(angle) | |
sprite("Space Art:Part Green Hull 4",0,0) | |
popMatrix() | |
table.insert(body,1,{prevx=x,prevy=y,prevangle=angle}) | |
--bit of tidying up to limit the size of the body table and by extension the size of the snake. without it I guess a memory limit could be reached | |
for i=1200,#body do | |
table.remove(body) | |
end | |
end | |
--# Step1 | |
-- Snake tutorial | |
-- by West | |
--1. Place a sprite on the screen | |
function setup() | |
displayMode(FULLSCREEN) | |
end | |
function draw() | |
background(40, 40, 50) | |
--place the sprite at position 400,400 on the screen. Chose this sprite as it sort of looks like a snakes head | |
sprite("Space Art:Part Green Hull 4",400,400) | |
end | |
--# Step2 | |
-- Snake tutorial | |
-- by West | |
--2. Add x and y variables to control the position | |
function setup() | |
displayMode(FULLSCREEN) | |
--variable x to control the horizontal position of the snake head | |
x=300 | |
--variable y to control the vertical position of the snake head | |
y=500 | |
end | |
function draw() | |
background(40, 40, 50) | |
--place the sprite at position x,y - you can change these in setup and later we will be changing these values in the draw loop to generate movement | |
sprite("Space Art:Part Green Hull 4",x,y) | |
end | |
--# Step3 | |
-- Snake tutorial | |
-- by West | |
--3. Rotate the sprite | |
function setup() | |
displayMode(FULLSCREEN) | |
x=300 | |
y=500 | |
end | |
function draw() | |
background(40, 40, 50) | |
--Unfortunately there is not an easy angle function included in sprite like the x and y position so a slightly more complex set of steps is required. This is a powerful approach for complex movements or transformations particularly when working in 3D but does mean the simple task of rotating a sprite is a bit more complex. | |
--The basics are: | |
--1.that the sets of "transforms" or movements in the x and y direction, along with any rotations should start with the pushMatrix() statement and end with the popMatrix() statement. | |
--2. The order in which the statements are executed is reversed between the popMatrix and pushMatrix commands. That is to say that bottom most statement is executed first, followed by the second bottom and so on | |
--3. The statements stack. For example rotating by 90 degrees then rotating by another 90 degrees means the sprite will be rotated by 180 degrees | |
--4. Rotate requires and angle in degrees and rotates ANTICLOCKWISE as a default (you can specify axis of rotation but this is too complex for just now) | |
--the following three examples show the effect of the different orders | |
--Example 1 - Green sprite. The sprite is drawn at 0,0 (bottom left) then rotated 20 degrees anticlockwise then moved by 300 along the x axis then 500 along the y axis | |
pushMatrix() | |
translate(x,y) --executed 3rd -move sprite by x along x axis and y along y axis | |
rotate(20) --executed 2nd - rotate sprite by 20 degrees anticlockwise | |
sprite("Space Art:Part Green Hull 4",0,0) --executed 1st - draw sprite at 0,0 | |
popMatrix() | |
--Example 2 - Red sprite. The sprite is drawn at 0,0 (bottom left) then moved 300 along the x axis and 500 along the y axis, then rotated by 20 degrees ABOUT THE ORIGIN OR BOTTOM LEFT CORNER. The sprite effectively follows the circumference of a circle. | |
--if you change the rotate(20) to rotate(ElapsedTime*25) you will see the path of the sprite | |
pushMatrix() | |
rotate(20) --executed 3rd - rotate sprite by 20 degrees anticlockwise | |
translate(x,y) --executed 2nd -move sprite by x along x axis and y along y axis | |
sprite("Space Art:Part Red Hull 4",0,0) --executed 1st - draw sprite at 0,0 | |
popMatrix() | |
-- Example 3 - Gray sprite. the first two commands have no sprite to act on so do nothing | |
pushMatrix() | |
sprite("Space Art:Part Gray Hull 4",0,0) --executed 3rd - draw sprite at 0,0 | |
translate(x,y) --executed 2nd - does nothing | |
rotate(20) --executed 1st - does nothing | |
popMatrix() | |
end | |
--# Step4 | |
-- Snake tutorial | |
-- by West | |
--4. Add a variable, angle, to control the rotation of the sprite | |
function setup() | |
displayMode(FULLSCREEN) | |
x=300 | |
y=500 | |
angle=90 --variable to control the orientation of the sprite | |
end | |
function draw() | |
background(40, 40, 50) | |
pushMatrix() | |
translate(x,y) | |
rotate(angle) --rotation controlled by variable angle | |
sprite("Space Art:Part Green Hull 4",0,0) | |
popMatrix() | |
end | |
--# Step5 | |
-- Snake tutorial | |
-- by West | |
--5. Control rotation through screen tapping. Also restrict the game to landscape only | |
function setup() | |
displayMode(FULLSCREEN) | |
supportedOrientations(LANDSCAPE_ANY) --locks the screen to use only landscape | |
x=300 | |
y=500 | |
angle=90 | |
end | |
function draw() | |
background(40, 40, 50) | |
--this simple example will use the CurrentTouch command. A more advanced (and better) way would be to handle touches separately. This may be explored later. | |
-- check to see if the screen has been touched | |
if CurrentTouch.state==BEGAN or CurrentTouch.state==MOVING then | |
--the state of the current touch is active then | |
angle = angle + 1 --increase the angle | |
end | |
pushMatrix() | |
translate(x,y) | |
rotate(angle) | |
sprite("Space Art:Part Green Hull 4",0,0) | |
popMatrix() | |
end | |
--# Step6 | |
-- Snake tutorial | |
-- by West | |
--6. More advanced control to allow rotation in both directions | |
function setup() | |
displayMode(FULLSCREEN) | |
supportedOrientations(LANDSCAPE_ANY) | |
x=300 | |
y=500 | |
angle=90 | |
end | |
function draw() | |
background(40, 40, 50) | |
if CurrentTouch.state==BEGAN or CurrentTouch.state==MOVING then | |
--test to see if the touch occured on the left hand side of the screen | |
if CurrentTouch.x<WIDTH/2 then --if the x position of the touch is less the half the screen width (WIDTH) | |
angle = angle + 2 --increase the angle which turns anticlockwise | |
else --if it isn't then the touch must have happened on the right | |
angle = angle -2 --decrease the angle which turns clockwise | |
end | |
end | |
pushMatrix() | |
translate(x,y) | |
rotate(angle) | |
sprite("Space Art:Part Green Hull 4",0,0) | |
popMatrix() | |
end | |
--# Step7 | |
-- Snake tutorial | |
-- by West | |
--7. Add a variable turning to control the rate of turning | |
function setup() | |
displayMode(FULLSCREEN) | |
supportedOrientations(LANDSCAPE_ANY) | |
x=300 | |
y=500 | |
angle=90 | |
turning=2 | |
end | |
function draw() | |
background(40, 40, 50) | |
if CurrentTouch.state==BEGAN or CurrentTouch.state==MOVING then | |
if CurrentTouch.x<WIDTH/2 then | |
angle = angle + turning --use the turning variable | |
else | |
angle = angle - turning --use the turning variable | |
end | |
end | |
pushMatrix() | |
translate(x,y) | |
rotate(angle) | |
sprite("Space Art:Part Green Hull 4",0,0) | |
popMatrix() | |
end | |
--# Step8 | |
-- Snake tutorial | |
-- by West | |
--8. Add movement | |
function setup() | |
displayMode(FULLSCREEN) | |
supportedOrientations(LANDSCAPE_ANY) | |
x=300 | |
y=500 | |
angle=90 | |
turning=2 | |
speed=2.5 --a variable to hold the current speed of the snake | |
end | |
function draw() | |
background(40, 40, 50) | |
if CurrentTouch.state==BEGAN or CurrentTouch.state==MOVING then | |
if CurrentTouch.x<WIDTH/2 then | |
angle = angle + turning --use the turning variable | |
else | |
angle = angle - turning --use the turning variable | |
end | |
end | |
--change the x and y coordinates based on the current direction. The direction needs to be resolved into its x and y components using simple trigonometry. The variable speed will be used to control the magnitude of the components. | |
--math.sin is the sine function - I assume you know what this is - you should have learned trigonometry at school. If you are still at school - ask your teacher. | |
--in codea, the trig functions require the angles to be provided in radians not degrees. Fortunately there is an in built function to convert from degrees to radians called math.rad(). Again I will assume you know what radians are, but if you don't either use the function blindly or find out! | |
--Finally, the angle is negative. I'm not sure why but reckon it's linked back to the rotate function being anticlockwise | |
x = x + speed*math.sin(math.rad(-angle)) | |
y = y + speed*math.cos(math.rad(-angle)) | |
pushMatrix() | |
translate(x,y) | |
rotate(angle) | |
sprite("Space Art:Part Green Hull 4",0,0) | |
popMatrix() | |
end | |
--# Step9 | |
-- Snake tutorial | |
-- by West | |
--9. Add a body part | |
function setup() | |
displayMode(FULLSCREEN) | |
supportedOrientations(LANDSCAPE_ANY) | |
x=300 | |
y=500 | |
angle=90 | |
turning=2 | |
speed=2.5 | |
--three variables to hold the x,y and angle of the previous position of the head | |
prevx=x | |
prevy=y | |
prevangle=angle | |
end | |
function draw() | |
background(40, 40, 50) | |
if CurrentTouch.state==BEGAN or CurrentTouch.state==MOVING then | |
if CurrentTouch.x<WIDTH/2 then | |
angle = angle + turning --use the turning variable | |
else | |
angle = angle - turning --use the turning variable | |
end | |
end | |
x = x + speed*math.sin(math.rad(-angle)) | |
y = y + speed*math.cos(math.rad(-angle)) | |
--draw the body befor the head so the head will appear on top | |
--use the same routine but use the prev variables | |
pushMatrix() | |
translate(prevx,prevy) | |
rotate(prevangle) | |
sprite("Space Art:Part Green Hull 5",0,0) | |
popMatrix() | |
pushMatrix() | |
translate(x,y) | |
rotate(angle) | |
sprite("Space Art:Part Green Hull 4",0,0) | |
popMatrix() | |
--update the prev variables with the current ones (which will be the old ones next time the draw loop executes) | |
prevx=x | |
prevy=y | |
prevangle=angle | |
end | |
--# Step10 | |
-- Snake tutorial | |
-- by West | |
--10. Add a delay to the position of the body part | |
function setup() | |
displayMode(FULLSCREEN) | |
supportedOrientations(LANDSCAPE_ANY) | |
x=300 | |
y=500 | |
angle=90 | |
turning=2 | |
speed=2.5 | |
--turn the three variables into a table called body | |
body={} | |
end | |
function draw() | |
background(40, 40, 50) | |
if CurrentTouch.state==BEGAN or CurrentTouch.state==MOVING then | |
if CurrentTouch.x<WIDTH/2 then | |
angle = angle + turning --use the turning variable | |
else | |
angle = angle - turning --use the turning variable | |
end | |
end | |
x = x + speed*math.sin(math.rad(-angle)) | |
y = y + speed*math.cos(math.rad(-angle)) | |
--do a check to see if the table size is bigger than 12. The # symbol in front of the table name gives its size | |
--Position 12 in the table will indicate where the head was 12 cycles of the draw function ago. this is where we want to put the first body piece | |
if #body>12 then | |
pushMatrix() | |
translate(body[12].prevx,body[12].prevy) | |
rotate(body[12].prevangle) | |
sprite("Space Art:Part Green Hull 5",0,0) | |
popMatrix() | |
end | |
pushMatrix() | |
translate(x,y) | |
rotate(angle) | |
sprite("Space Art:Part Green Hull 4",0,0) | |
popMatrix() | |
--add the current head position into the table at the start. this will shove everything along one so the old position | |
table.insert(body,1,{prevx=x,prevy=y,prevangle=angle}) | |
end | |
--# Step11 | |
-- Snake tutorial | |
-- by West | |
--11. Add a second body part | |
function setup() | |
displayMode(FULLSCREEN) | |
supportedOrientations(LANDSCAPE_ANY) | |
x=300 | |
y=500 | |
angle=90 | |
turning=2 | |
speed=2.5 | |
body={} | |
end | |
function draw() | |
background(40, 40, 50) | |
if CurrentTouch.state==BEGAN or CurrentTouch.state==MOVING then | |
if CurrentTouch.x<WIDTH/2 then | |
angle = angle + turning | |
else | |
angle = angle - turning | |
end | |
end | |
x = x + speed*math.sin(math.rad(-angle)) | |
y = y + speed*math.cos(math.rad(-angle)) | |
--Exactly the same as the first body part except the position is taken from 24 frames (cycles of draw) ago. Again a check to make sure there at least 24 previous positions recorded | |
if #body>20 then | |
pushMatrix() | |
translate(body[20].prevx,body[20].prevy) | |
rotate(body[20].prevangle) | |
sprite("Space Art:Part Green Hull 5",0,0) | |
popMatrix() | |
end | |
if #body>12 then | |
pushMatrix() | |
translate(body[12].prevx,body[12].prevy) | |
rotate(body[12].prevangle) | |
sprite("Space Art:Part Green Hull 5",0,0) | |
popMatrix() | |
end | |
pushMatrix() | |
translate(x,y) | |
rotate(angle) | |
sprite("Space Art:Part Green Hull 4",0,0) | |
popMatrix() | |
table.insert(body,1,{prevx=x,prevy=y,prevangle=angle}) | |
end | |
--# Step12 | |
-- Snake tutorial | |
-- by West | |
--12. Add a third body part | |
function setup() | |
displayMode(FULLSCREEN) | |
supportedOrientations(LANDSCAPE_ANY) | |
x=300 | |
y=500 | |
angle=90 | |
turning=2 | |
speed=2.5 | |
body={} | |
end | |
function draw() | |
background(40, 40, 50) | |
if CurrentTouch.state==BEGAN or CurrentTouch.state==MOVING then | |
if CurrentTouch.x<WIDTH/2 then | |
angle = angle + turning | |
else | |
angle = angle - turning | |
end | |
end | |
x = x + speed*math.sin(math.rad(-angle)) | |
y = y + speed*math.cos(math.rad(-angle)) | |
--same again just with a different frame position | |
if #body>28 then | |
pushMatrix() | |
translate(body[28].prevx,body[28].prevy) | |
rotate(body[28].prevangle) | |
sprite("Space Art:Part Green Hull 5",0,0) | |
popMatrix() | |
end | |
if #body>20 then | |
pushMatrix() | |
translate(body[20].prevx,body[20].prevy) | |
rotate(body[20].prevangle) | |
sprite("Space Art:Part Green Hull 5",0,0) | |
popMatrix() | |
end | |
if #body>12 then | |
pushMatrix() | |
translate(body[12].prevx,body[12].prevy) | |
rotate(body[12].prevangle) | |
sprite("Space Art:Part Green Hull 5",0,0) | |
popMatrix() | |
end | |
pushMatrix() | |
translate(x,y) | |
rotate(angle) | |
sprite("Space Art:Part Green Hull 4",0,0) | |
popMatrix() | |
table.insert(body,1,{prevx=x,prevy=y,prevangle=angle}) | |
end | |
--# Step13 | |
-- Snake tutorial | |
-- by West | |
--13. Handle body parts as a loop | |
function setup() | |
displayMode(FULLSCREEN) | |
supportedOrientations(LANDSCAPE_ANY) | |
x=300 | |
y=500 | |
angle=90 | |
turning=2 | |
speed=2.5 | |
body={} | |
numBodyParts=25 -- variable to hold the current number of body parts | |
end | |
function draw() | |
background(40, 40, 50) | |
if CurrentTouch.state==BEGAN or CurrentTouch.state==MOVING then | |
if CurrentTouch.x<WIDTH/2 then | |
angle = angle + turning | |
else | |
angle = angle - turning | |
end | |
end | |
x = x + speed*math.sin(math.rad(-angle)) | |
y = y + speed*math.cos(math.rad(-angle)) | |
-- create a loop where we repeat a bit of code as many times as we specify in the loop. In this case we are repeating it 25 times because numBodyParts is 25. If we had continued with the approach shown in steps 11 and 12, the code would quickly become long and repetitive | |
for i=1,numBodyParts do | |
local reqFrame=4+(i*8) -- this is a local variable - only used inside this loop and gives us the number of the frame based ona simple formula. | |
--the first time round the loop, the value of i is 1 and therefore reqFrame is 12. | |
--Second time round the loop i is 2 and reqFrame is 4+(2*8)=20 | |
--Third time round it i is 3 and reqFrame is 4+(3*8)=28 | |
--looking back to the previous steps this number is the only thing that changed in the block of code that prints out the body part. | |
--Therefore we can replace thenumber with this local variable | |
if #body>reqFrame then | |
pushMatrix() | |
translate(body[reqFrame].prevx,body[reqFrame].prevy) | |
rotate(body[reqFrame].prevangle) | |
sprite("Space Art:Part Green Hull 5",0,0) | |
popMatrix() | |
end | |
end | |
pushMatrix() | |
translate(x,y) | |
rotate(angle) | |
sprite("Space Art:Part Green Hull 4",0,0) | |
popMatrix() | |
table.insert(body,1,{prevx=x,prevy=y,prevangle=angle}) | |
end | |
--# Step14 | |
-- Snake tutorial | |
-- by West | |
--14. Reverse the loop to draw from the tail forward | |
function setup() | |
displayMode(FULLSCREEN) | |
supportedOrientations(LANDSCAPE_ANY) | |
x=300 | |
y=500 | |
angle=90 | |
turning=2 | |
speed=2.5 | |
body={} | |
numBodyParts=25 -- variable to hold the current number of body parts | |
end | |
-- This function gets called once every frame | |
function draw() | |
-- This sets a dark background color | |
background(40, 40, 50) | |
if CurrentTouch.state==BEGAN or CurrentTouch.state==MOVING then | |
if CurrentTouch.x<WIDTH/2 then | |
angle = angle + turning | |
else | |
angle = angle - turning | |
end | |
end | |
x = x + speed*math.sin(math.rad(-angle)) | |
y = y + speed*math.cos(math.rad(-angle)) | |
--Instead of counting up from 1 to 25 (numBodyParts) we want to count down. normally with loops, the step size is 1, but we can alter this by specifying a third parameter, | |
--this now basically reads as: go from 25 (numBodyParts) to 1 in steps of 1 (downwards - in other words -1) and use i to store which position you are currently at | |
for i=numBodyParts,1,-1 do | |
local reqFrame=4+(i*8) | |
if #body>reqFrame then | |
pushMatrix() | |
translate(body[reqFrame].prevx,body[reqFrame].prevy) | |
rotate(body[reqFrame].prevangle) | |
sprite("Space Art:Part Green Hull 5",0,0) | |
popMatrix() | |
end | |
end | |
pushMatrix() | |
translate(x,y) | |
rotate(angle) | |
sprite("Space Art:Part Green Hull 4",0,0) | |
popMatrix() | |
table.insert(body,1,{prevx=x,prevy=y,prevangle=angle}) | |
end | |
--# Step15 | |
-- Snake tutorial | |
-- by West | |
--15. Create "edible" mushrooms at a random screen position | |
function setup() | |
displayMode(FULLSCREEN) | |
supportedOrientations(LANDSCAPE_ANY) | |
x=300 | |
y=500 | |
angle=90 | |
turning=2 | |
speed=2.5 | |
body={} | |
numBodyParts=25 | |
mushx=50+math.random(WIDTH-100)--pick a random screen x location which is at least 50 pixels away from both the left and right sides | |
mushy=50+math.random(HEIGHT-100)--pick a random screen y location which is at least 50 pixels away from the top and bottom edges | |
end | |
function draw() | |
background(40, 40, 50) | |
if CurrentTouch.state==BEGAN or CurrentTouch.state==MOVING then | |
if CurrentTouch.x<WIDTH/2 then | |
angle = angle + turning | |
else | |
angle = angle - turning | |
end | |
end | |
x = x + speed*math.sin(math.rad(-angle)) | |
y = y + speed*math.cos(math.rad(-angle)) | |
--draw a sprite for the mushroom at the appropriate position | |
sprite("Platformer Art:Mushroom",mushx,mushy) | |
for i=numBodyParts,1,-1 do | |
local reqFrame=4+(i*8) | |
if #body>reqFrame then | |
pushMatrix() | |
translate(body[reqFrame].prevx,body[reqFrame].prevy) | |
rotate(body[reqFrame].prevangle) | |
sprite("Space Art:Part Green Hull 5",0,0) | |
popMatrix() | |
end | |
end | |
pushMatrix() | |
translate(x,y) | |
rotate(angle) | |
sprite("Space Art:Part Green Hull 4",0,0) | |
popMatrix() | |
table.insert(body,1,{prevx=x,prevy=y,prevangle=angle}) | |
end | |
--# Step16 | |
-- Snake tutorial | |
-- by West | |
--16. Add collision detection to allow the mushrooms to be picked up. Start with a smaller snake (5) and each mushroom will make the snake longer. Make the snake turn tighter by increasing the turning value | |
function setup() | |
displayMode(FULLSCREEN) | |
supportedOrientations(LANDSCAPE_ANY) | |
x=300 | |
y=500 | |
angle=90 | |
turning=4 --increase the turning rate | |
speed=2.5 | |
body={} | |
numBodyParts=5 --set snake initial size to 5 | |
mushx=50+math.random(WIDTH-100) | |
mushy=50+math.random(HEIGHT-100) | |
end | |
function draw() | |
background(40, 40, 50) | |
if CurrentTouch.state==BEGAN or CurrentTouch.state==MOVING then | |
if CurrentTouch.x<WIDTH/2 then | |
angle = angle + turning | |
else | |
angle = angle - turning | |
end | |
end | |
x = x + speed*math.sin(math.rad(-angle)) | |
y = y + speed*math.cos(math.rad(-angle)) | |
sprite("Platformer Art:Mushroom",mushx,mushy) | |
--check to see if the snake head and the mushroom overlap | |
--this compares the magnitude of the difference between the x value of the snake head and the x vale of the mushroom and if it is close enough (along with a similar comparison of the y values) then a collision is detected | |
if math.abs(x-mushx)<40 and math.abs(y-mushy)<40 then | |
numBodyParts = numBodyParts + 1 --increase the length of the snake | |
mushx=50+math.random(WIDTH-100) --create new position for next mushroom | |
mushy=50+math.random(HEIGHT-100) | |
end | |
for i=numBodyParts,1,-1 do | |
local reqFrame=4+(i*8) | |
if #body>reqFrame then | |
pushMatrix() | |
translate(body[reqFrame].prevx,body[reqFrame].prevy) | |
rotate(body[reqFrame].prevangle) | |
sprite("Space Art:Part Green Hull 5",0,0) | |
popMatrix() | |
end | |
end | |
pushMatrix() | |
translate(x,y) | |
rotate(angle) | |
sprite("Space Art:Part Green Hull 4",0,0) | |
popMatrix() | |
table.insert(body,1,{prevx=x,prevy=y,prevangle=angle}) | |
end | |
--# Step17 | |
-- Snake tutorial | |
-- by West | |
--17. Add collision detection with itself and the walls | |
function setup() | |
displayMode(FULLSCREEN) | |
supportedOrientations(LANDSCAPE_ANY) | |
x=300 | |
y=500 | |
angle=90 | |
turning=4 | |
speed=2.5 | |
body={} | |
numBodyParts=5 | |
mushx=50+math.random(WIDTH-100) | |
mushy=50+math.random(HEIGHT-100) | |
end | |
function draw() | |
background(40, 40, 50) | |
if CurrentTouch.state==BEGAN or CurrentTouch.state==MOVING then | |
if CurrentTouch.x<WIDTH/2 then | |
angle = angle + turning | |
else | |
angle = angle - turning | |
end | |
end | |
x = x + speed*math.sin(math.rad(-angle)) | |
y = y + speed*math.cos(math.rad(-angle)) | |
sprite("Platformer Art:Mushroom",mushx,mushy) | |
if math.abs(x-mushx)<40 and math.abs(y-mushy)<40 then | |
numBodyParts = numBodyParts + 1 | |
mushx=50+math.random(WIDTH-100) | |
mushy=50+math.random(HEIGHT-100) | |
end | |
--check to see if the snake has gone outside the screen boundaries | |
if x<0 or x>WIDTH or y<0 or y>HEIGHT then | |
--add a flash | |
background(math.random(255),math.random(255),math.random(255)) | |
end | |
--check to see if the snake has collided with itself. Don't check the first few segments as they will naturally be near the head but the turning circle shouldn't be tight enough to allow the head to "eat" these first sections | |
for i=4,numBodyParts do | |
local reqFrame=4+(i*8) | |
if #body>reqFrame and math.abs(x-body[reqFrame].prevx)<25 and math.abs(y-body[reqFrame].prevy)<25 then | |
--add a flash | |
background(math.random(255),math.random(255),math.random(255)) | |
end | |
end | |
for i=numBodyParts,1,-1 do | |
local reqFrame=4+(i*8) | |
if #body>reqFrame then | |
pushMatrix() | |
translate(body[reqFrame].prevx,body[reqFrame].prevy) | |
rotate(body[reqFrame].prevangle) | |
sprite("Space Art:Part Green Hull 5",0,0) | |
popMatrix() | |
end | |
end | |
pushMatrix() | |
translate(x,y) | |
rotate(angle) | |
sprite("Space Art:Part Green Hull 4",0,0) | |
popMatrix() | |
table.insert(body,1,{prevx=x,prevy=y,prevangle=angle}) | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment