(Another) Snake Game - Getting The Snake To Collide With Itself
Author |
Message |
Kaykao
|
Posted: Thu Oct 24, 2013 7:36 pm Post subject: (Another) Snake Game - Getting The Snake To Collide With Itself |
|
|
What is it you are trying to achieve?
I'm making (yet another) version of snake.
What is the problem you are having?
I've got almost everything down, I even managed to teach myself 2D arrays for this, and the snake collides with the edges of the board alright. But I can't get the head to collide with the body properly. :/
Describe what you have tried to solve this problem
I've tried plenty of if statements within two for loops, with every 'if' I tried having many varieties of requirements that must be met to say you lost, and all basically just checking if the head's coordinates are the same as the coordinates of any body block. But for some reason, when I try something like that, the snake's head 'collides' with itself when there is only one blank block between it and any body blocks.
I've also tried setting the coordinates of all the body blocks as 1 the same value I set the border tiles to) on the main grid with a similar if-statement-within-two-for-loops structure, but I can't figure out how to make that temporary and set each tile back being empty (0) when there are no more body blocks in it.
I've looked through so many threads about snake help and collision tutorials around here that my brain hurts, but I can't seem to find anything that helps me out.
...Keep in mind that this year I'm taking my first compsci class in my life, so even if the answer seems obvious to you I'm probably having trouble because I am a programming newb.
Post any relevant code (You may choose to attach the file instead of posting the code if it is too long)
If you decide to run it, use the w, a, s, and d keys to move the snake. (Just in case you skim over that part. )
Also, keep in mind that eventually I will be adding my own simple sprites and things once I sort out this problem, so I need help finding a solution that can be made to work with images too.
Turing: |
% declare variables and constants
var window : int := Window.Open ("graphics:500;500")
var grid : array 0 .. 39, 0 .. 39 of int
var score : int := 0
var body_x, body_y : flexible array 1 .. 1 of int
var arrows : array char of boolean
var direction : int := 0
var food_x, food_y : int := Rand.Int (1, 38)
var player_x, player_y : int := 20
const width : int := 12
% set the grid's values
for x : 0 .. 39
for y : 0 .. 39
grid (x, y ) := 0
end for
end for
for x : 0 .. 39
grid (x, 0) := 1
grid (x, 39) := 1
end for
for y : 0 .. 39
grid (0, y ) := 1
grid (39, y ) := 1
end for
View.Set ("offscreenonly")
loop
% redraw the grid
for x : 0 .. 39
for y : 0 .. 39
if grid (x, y ) = 1 then
Draw.FillBox (x * width, y * width, x * width + width, y * width + width, red)
end if
end for
end for
locate (1, 1)
put "Score: ", score
% draw snake's body
for decreasing a : upper (body_x ) .. 2
body_x (a ) := body_x (a - 1)
body_y (a ) := body_y (a - 1)
Draw.FillBox (body_x (a ) * width, body_y (a ) * width, body_x (a ) * width + width,
body_y (a ) * width + width, brightgreen)
Draw.Box (body_x (a ) * width, body_y (a ) * width, body_x (a ) * width + width,
body_y (a ) * width + width, black)
end for
body_x (1) := player_x
body_y (1) := player_y
Draw.FillBox (body_x (1) * width, body_y (1) * width, body_x (1) * width + width,
body_y (1) * width + width, brightgreen)
Draw.Box (body_x (1) * width, body_y (1) * width, body_x (1) * width + width,
body_y (1) * width + width, black)
% set movement direction
Input.KeyDown (arrows )
if arrows ('a') and direction not= 2 then
direction := 1
elsif arrows ('d') and direction not= 1 then
direction := 2
elsif arrows ('s') and direction not= 4 then
direction := 3
elsif arrows ('w') and direction not= 3 then
direction := 4
end if
% check if snake has hit edge
if direction = 1 and grid (player_x - 1, player_y ) = 1 then
exit
elsif direction = 2 and grid (player_x + 1, player_y ) = 1 then
exit
elsif direction = 3 and grid (player_x, player_y - 1) = 1 then
exit
elsif direction = 4 and grid (player_x, player_y + 1) = 1 then
exit
end if
% move snake
if direction = 1 and grid (player_x - 1, player_y ) = 0 then
player_x - = 1
elsif direction = 2 and grid (player_x + 1, player_y ) = 0 then
player_x + = 1
elsif direction = 3 and grid (player_x, player_y - 1) = 0 then
player_y - = 1
elsif direction = 4 and grid (player_x, player_y + 1) = 0 then
player_y + = 1
end if
% add to the score, regenerate the food, grow the snake
if player_x = food_x and player_y = food_y then
score + = 1
food_x := Rand.Int (1, 38)
food_y := Rand.Int (1, 38)
new body_x, upper (body_x, 1) + 1
new body_y, upper (body_y, 1) + 1
end if
% draw food
Draw.FillBox (food_x * width, food_y * width, food_x * width + width,
food_y * width + width, purple)
% draw snake's head
Draw.FillBox (player_x * width, player_y * width, player_x * width + width,
player_y * width + width, green)
Draw.Box (player_x * width, player_y * width, player_x * width + width,
player_y * width + width, black)
View.Update
delay (100)
cls
end loop
|
Please specify what version of Turing you are using
4.1, because of 4.1.1's weird .exe bugs.
As a relatively unimportant sidenote: I plan to make this Doctor Who themed somehow once it's done, as part of a much larger project I've decided to tackle out of boredom. So if anyone has any ideas on what I could make the snake, food, etc look like when I add in the images, please share!  |
|
|
|
|
 |
Sponsor Sponsor

|
|
 |
Dragon20942

|
Posted: Mon Oct 28, 2013 8:37 pm Post subject: RE:(Another) Snake Game - Getting The Snake To Collide With Itself |
|
|
Keep track of all of the snake parts' coordinates so that you can check if the snake is moving into an occupied grid. I understand this is what you've been doing for the boundaries. The boundaries can be changed by checking the direction and whether the head is in the upper or lower bound of the array. |
|
|
|
|
 |
Kaykao
|
Posted: Tue Oct 29, 2013 5:28 pm Post subject: Re: (Another) Snake Game - Getting The Snake To Collide With Itself |
|
|
Ah... Your advice nudged me in the right direction and now it works. Thank you Dragon, that was an immense help.
In case anyone is curious, these are the key things I added (mind you the program has been modified a LOT since I posted this...):
Turing: |
var lives : int := 4
% ... other code here ...
% check if snake has hit itself
for a : 2 .. upper (body_x )
if grid (player_x - 1, player_y ) = grid (body_x (a ), body_y (a )) then
lives - = 1
% code for resetting the snake goes here, taken out
% so as not to bore you all...
end if
end for
% check if snake is 'dead'
if lives = 0 then
exit
end if
|
|
|
|
|
|
 |
|
|