Challenge #16 - Snake Game

Started by kevin, March 01, 2009, 06:44:35 AM

Previous topic - Next topic

kevin





Challenge #16 - Snake Game


     This is an another retro game remake challenge.  Your objective is to make your own version of the classic Snake / Tron game.    In your edition of  game,  the player will guide the snakes head in four directions using the keys or joy pad.  The snake is constantly moving,  it should never stop.   It can not move over/through itself or screen edges (or other walls).   So if it's moving left,  the player would die if they try to move right. 

    The objective is to guide to snake (without touching it self or the walls) to pick up a food items.  You pick up items by running into them with the snakes head.  With each item the snake eats,  it grows one link longer.     Food items should appear randomly on the screen, for a random amount of time, before moving to another location.  So the player has to react quickly to collect them.  As an added bonus the player could have a health bar,  indicating how it's been since the player last ate.  if the bar runs out, the snake dies from starvation.

    While a very simple game on the surface,  it includes a number of good challenges for new game programmers.  Namely , getting your head around object management.  So you're going to have to build some code to cope with managing the various food items objects, the snakes growing length and the collisions between the snake and the food and snake and itself... 

     As with all challenges, the visuals/physics are not important, the challenge here is core game mechanic.  Good luck


Reference Materials

  Epic Snake



Submission

* Submissions can be written in any version of PlayBasic

* Submission can only be accepted in Source Code form only.

* Authors can use external Media (images/music) provided you created the media/and or have permission to distribute the includes media or the Media is in the public domain.

* Zip up your Submissions and please try to keep it smaller than 500K !

* Authors automatically give consent for their submission(s) to distributed and used for promotional purposes via UnderwareDesign.com, PlayBasic code tank.

* Authors can submit as many times as they like.

* To make a submission, zip up your projects source code + media and either post it in this thread, or create your own thread in either the Source Codes or Show Case forums and post a link bellow.



Dead Line

Anytime before the next ice age



Prizes

     * The Best submissions will be periodically highlighted through the Playbasic IDE news service. 





Big C.

#1
ok here is my mockup...

PlayBASIC Code: [Select]
; PROJECT : Snake-Challenge-Light
; AUTHOR : Big C.
; CREATED : 03.03.2009
; EDITED : 08.03.2009
; ---------------------------------------------------------------------

RemStart
Your task is to guide the snake so it eats the food.
The quicker you eat, the more you score.
And just like real food-eating snakes, the more you gobble,
the longer you become. Try To steer clear of your own
growing tail (and avoid the walls in a future version)...
it won't be long before it's game over.

Features:

08.03.09 V0.02
- If it's moving left, the player would die if they try to move right.
- It can not move through screen edges.
- Some minor changes

06.03.09 V0.01
- The player will guide the snakes head in four directions using the keys
- The snake is constantly moving, it should never stop.
- It can not move over/through itself
- Food items should appear randomly on the screen
- Pick up items by running into them with the snakes head
- With each item the snake eats, it grows one link longer.

ToDo's:
- It can not move through other ingame walls (in future version).
- Food items should appear for a random amount of time, before moving to another location.
- Bonus: The player could have a health bar, indicating how it's been since the player last ate.
If the bar runs out, the snake dies from starvation.

RemEnd


OpenScreen 640,480,16,1

TitleScreen "Challenge #16 - Snake Game coded with PB V1.64i - V0.02"

Constant North = 1
Constant East = 2
Constant South = 3
Constant West = 4

Global Direction = East

Global Head_X = 15 ;starting X-Point of our Snake-Head
Global Head_Y = 12 ;starting Y-Point of our Snake-Head
Global Food_X = RndRange(0, 63)
Global Food_Y = RndRange(0, 47)

Global Eat = 0
Global Score = 0
Global Size = 0
Global GameOver = 0

Global GetTime
Global LastMove = 0

; This Type define the position of body item
Type TSnake
PosX
PosY
EndType

;create a Linked List for the snakebody
Dim Snake As TSnake List

;our snake-body has 5 items
/*For I = 0 To 4
Snake = New TSnake
Snake.PosX = Head_X - 5 + I
Snake.PosY = Head_Y
Next I*/


Psub CheckInput()
;check for North and not South
If UpKey()
If Direction <> South
Direction = North
Else
GameOver = 1
EndIf
EndIf

;check for East and not West
If RightKey()
If Direction <> West
Direction = East
Else
GameOver = 1
EndIf
EndIf

;check for South and not North
If DownKey()
If Direction <> North
Direction = South
Else
GameOver = 1
EndIf
EndIf

;check for West and not East
If LeftKey()
If Direction <> East
Direction = West
Else
GameOver = 1
EndIf
EndIf
EndPsub

Psub MoveSnake()
GetTime = Timer()
;slow down the speed... after 75 millisec snake is moving
If (GetTime - LastMove) > 75
LastMove = GetTime

;check if snake has found something to eat
If Head_X = Food_X And Head_Y = Food_Y
Food_X = RndRange(0, 63)
Food_Y = RndRange(0, 47)
Eat = 1
Score = Score + 10
Else
Eat = 0
EndIf

;here we let snake growing... Everytime snake head is moving
;to a new tile create a new type instance
Snake = New TSnake
Snake.PosX = Head_X
Snake.PosY = Head_Y

Head_X = Head_X - (Direction=West) + (Direction=East)
Head_Y = Head_Y - (Direction=North) + (Direction=South)

If Head_X < 0 Or Head_X > 64 Or Head_Y < 0 Or Head_Y > 48
GameOver = 1
EndIf

/*If Head_X < 0 Then Head_X = 63
If Head_X > 63 Then Head_X = 0
If Head_Y < 0 Then Head_Y = 47
If Head_Y > 47 Then Head_Y = 0*/


Login required to view complete source code


For better understanding what is happend if snake didn't find to eat and is moving his body here is my testcode to check the Linked List.

PlayBASIC Code: [Select]
; PROJECT : Project1
; AUTHOR : Big C.
; CREATED : 06.03.2009
; EDITED : 06.03.2009
; ---------------------------------------------------------------------

Type TTest
Number
Item$
EndType

Dim Test As TTest List

Global i = 0

Do
Cls 0
Print "Up Arrow Key: New Object"
Print "Down Arrow Key: Delete First Item"

If UpKey()
i = i + 1
Test = New TTest
Test.Number = i
Test.Item$ = "Item"+Str$(i)
FlushKeys
EndIf

If DownKey()
For Each Test()
If GetListNext(Test()) = -1
First = GetListFirst(Test())
Item = GetListPos(Test())
Test = NULL
EndIf
Next
FlushKeys
EndIf

Print "ListSize: " + Str$(GetListSize(Test())) + " First: " + Str$(First) + " Pos: " + Str$(Item)

For Each Test()
Print "Nr. " + Str$(Test.Number) + " Item: " + Test.Item$ + " Position: " + Str$(GetListPos(Test()))
Next

Sync

Loop



08.03.09 Updat to V0.02... two less ToDo's

Big C.


micky4fun

#2
Hi Big C.

nice little demo , works very well , a 2 player version would be good i think , both players would have to race to pickup item while missing each other

thanks for posting code has help me a lot to understand the how segmant follows each other and more linked lists understanding

im going to give the challenge a go try and make a full game of it , but will post outcome if i get that far in the show case part of forum
as its not all my code , just modifyed snippets of playbasic demo's and would be totally unfair to this challenge..

thanks mick :)

Big C.

hey mick,

thx for comment...

Quotea 2 player version would be good i think

yes indeed but it increase the challenge requirements  ;)...  we will see...  :)

Hint for you: I've updated my entry post...

Big C.


micky4fun

Hi Big C.

Thanks for update , ile look forward to end result , nive to see how other coders do things , always pick up tips etc

thank for entry

mick :)

monkeybot

#5
here is a snake i knocked up.

I can get to about 400...just

PlayBASIC Code: [Select]
; PROJECT : snake
; AUTHOR : Monkeybot
; CREATED : 28/09/2009
; EDITED : 29/09/2009
; ---------------------------------------------------------------------
;TODO
;Function display() change this to linked list
;
;
explicit on
constant startLevel=5
constant Debug=0
constant maxLength=2000
constant pillnum=9
Constant pillsize=5
Constant up=3
Constant down=1
Constant left=4
Constant right=2
local ws
if (screenmodeExist(800,600,16)) then ws=false
if(ScreenModeExist(1366,768,16)) then ws=true;;

if ws=true
openscreen 1366,768,16,2
else
openscreen 800,600,16,2
endif


global highscore=0
do
global score=0
global dead=0
global gamespeed#=startlevel ;fps
setfps(50)
global gameloop=timer()
global countdownTimer=timer()
global radius#=10
global sHeight=getscreenheight()
global sWidth=getscreenwidth()
global speed=(radius#*2)-2
global length=6
global count=0
global dir=0
global txtdisplay=0
global time=0
global txtX,txtY,txts$
loadfont "ariel",1,40,1
loadfont "ariel",2,20,1
setfont 2
type snakebody
x,y,radius#,colour
endtype

type pills
x,y,value,display
endtype
dim sb(maxLength) as snakebody
dim pill1(pillnum) as pills
prepSnake()
preppills()

repeat
cls 0
score=length+gamespeed#*10
readkeys()
if timer()>gameloop then dosnake()
displaypills()
checkpills()
displaySnake()
displayScore()
if txtdisplay=1 then display()
increaseDiff()
if debug then debugInfo()
displayframe()
eyes()
;circlec sb(0).x,sb(0).y,4,0,$f0f0f0
sync
until dead
local x,y
x=swidth/2
y=sheight/2
setfont 1
cls 0
ink $ff0000

centertext x,y-40,"YOU ARE DEAD!!!!!!!"
centertext x,y,"You got "+str$(score)
if score>highscore then CenterText x,y+40,"Woooooo Highscore":highscore=score
centertext x,y+80,"press any key or Escape to quit"
sync
wait 1000
waitnokey
waitkey
loop
function eyes()
local x,y,angle#,xx#,yy#
;circlec sb(0).x,sb(0).y,4,0,$f0f0f0
x=sb(0).x
y=sb(0).y
angle#=(dir-1)*90
ink $ff00ff
xx#= x+(sin(angle#))*10
yy#= y+(cos(angle#))*10
circle xx#,yy#,5,0
line x,y,xx#,yy#
;circle (x+radius#)+sin(angle),(y+radius#)+cos(angle),5,0
endfunction

Function increaseDiff()
local l
if timer()>countdownTimer
if gamespeed#<10 then gamespeed#=gamespeed#+0.4;+l)
countdownTimer=timer()+30000
endif
EndFunction

Function readkeys()
local k
shitter:
k=scancode()
if k=200 then dir=up
if k=208 then dir=down
if k=203 then dir=left
if k=205 then dir=right
if k=57 and length<maxLength then length=length+1;:moveVars()
if k=25 then waitnokey:waitkey
EndFunction


Function movevars()
local q
for q=length-1 to 0 step-1
sb(q+1).x=sb(q).x
sb(q+1).y=sb(q).y
sb(q+1).radius#=sb(q).radius#
sb(q+1).colour=sb(q).colour
sb(q).colour=$00ff00

next
EndFunction


Function displaySnake()
local q
ink sb(0).colour=$00ff00
for q=0 to length
ink sb(q).colour
Login required to view complete source code



Big C.

n1 one monkeybot and very fast  :)

kevin


micky4fun

Hi , monkeybot 

not quite got 400 yet , but nearly there ,, nice program

mick :)


monkeybot