Files
prosperon/examples/snake/main.ce
2026-01-16 20:56:16 -06:00

121 lines
2.9 KiB
Plaintext

// main.js
var draw = use('draw2d')
var render = use('render')
var graphics = use('graphics')
var input = use('input')
var config = use('config')
var color = use('color')
var random = use('random')
prosperon.camera.transform.pos = [0,0]
var cellSize = 20
var gridW = floor(config.width / cellSize)
var gridH = floor(config.height / cellSize)
var snake, direction, nextDirection, apple
var moveInterval = 0.1
var moveTimer = 0
var gameState = "playing"
function resetGame() {
var cx = floor(gridW / 2)
var cy = floor(gridH / 2)
snake = [
{x: cx, y: cy},
{x: cx-1, y: cy},
{x: cx-2, y: cy}
]
direction = {x:1, y:0}
nextDirection = {x:1, y:0}
spawnApple()
gameState = "playing"
moveTimer = 0
}
function spawnApple() {
apple = {x:floor(random.random()*gridW), y:floor(random.random()*gridH)}
// Re-spawn if apple lands on snake
for (var i=0; i<snake.length; i++)
if (snake[i].x == apple.x && snake[i].y == apple.y) { spawnApple(); return }
}
function wrap(pos) {
if (pos.x < 0) pos.x = gridW - 1
if (pos.x >= gridW) pos.x = 0
if (pos.y < 0) pos.y = gridH - 1
if (pos.y >= gridH) pos.y = 0
}
resetGame()
this.update = function(dt) {
if (gameState != "playing") return
moveTimer += dt
if (moveTimer < moveInterval) return
moveTimer -= moveInterval
// Update direction
direction = {x: nextDirection.x, y: nextDirection.y}
// New head
var head = {x: snake[0].x + direction.x, y: snake[0].y + direction.y}
wrap(head)
// Check collision with body
for (var i=0; i<snake.length; i++) {
if (snake[i].x == head.x && snake[i].y == head.y) {
gameState = "gameover"
return
}
}
// Place head
snake.unshift(head)
// Eat apple?
if (head.x == apple.x && head.y == apple.y) spawnApple()
else snake.pop()
}
this.hud = function() {
// Optional clear screen
draw.rectangle({x:0, y:0, width:config.width, height:config.height}, [0,0,0,1])
// Draw snake
for (var i=0; i<snake.length; i++) {
var s = snake[i]
draw.rectangle({x:s.x*cellSize, y:s.y*cellSize, width:cellSize, height:cellSize}, color.green)
}
// Draw apple
draw.rectangle({x:apple.x*cellSize, y:apple.y*cellSize, width:cellSize, height:cellSize}, color.red)
if (gameState == "gameover") {
var msg = "GAME OVER! Press SPACE to restart."
draw.text(msg, {x:0, y:config.height*0.5-10, width:config.width, height:20}, null, 0, color.white)
}
}
// No immediate reversal
// "Up" means y=1, so going physically up on screen
this.inputs = {
up: function() {
if (direction.y != -1) nextDirection = {x:0,y:1}
},
down: function() {
if (direction.y != 1) nextDirection = {x:0,y:-1}
},
left: function() {
if (direction.x != 1) nextDirection = {x:-1,y:0}
},
right: function() {
if (direction.x != -1) nextDirection = {x:1,y:0}
},
space: function() {
if (gameState=="gameover") resetGame()
}
}
input.player[0].control(this)