Snake

Show off your games, demos and other (playable) creations.
Post Reply
anders
Prole
Posts: 1
Joined: Thu Mar 18, 2010 1:05 am

Snake

Post by anders »

Here is a late night creation, Snake! Likely terrible but thought I'd share anyways :)
EyXae.png
EyXae.png (15 KiB) Viewed 761 times

Code: Select all

local SCREEN_WIDTH = 800
local SCREEN_HEIGHT = 600

local BLOCKSIZE = 20
local HEIGHT = SCREEN_HEIGHT / BLOCKSIZE
local WIDTH = SCREEN_WIDTH / BLOCKSIZE

local DIRECTION_RIGHT = 1
local DIRECTION_LEFT = 2
local DIRECTION_UP = 3
local DIRECTION_DOWN = 4

local BLOCK_FOOD = 1
local BLOCK_WALL = 2

local LEVEL_LENGTH_MULT = 1.05

local function xy(x, y) return x * WIDTH + y end

local state

local function newfood()
	-- list of possible positions for the food
	local possible = {}

	for y=1, HEIGHT do
		for x=1, WIDTH do
			if not state.board[xy(x, y)] then
				local snakeFound = false
				for k, v in ipairs(state.snake) do
					if v.x == x and v.y == y then
						snakeFound = true
						break
					end
				end

				if not snakeFound then
					possible[#possible + 1] = {x = x, y = y}
				end
			end
		end
	end

	local newPos = possible[math.random(1, #possible)]
	state.board[xy(newPos.x, newPos.y)] = {type = BLOCK_FOOD, ttl = 10}
end

local function reset()
	state = {}
	state.snake = {{x = math.random(1, WIDTH), y = math.random(1, HEIGHT)}}
	state.board = {}
	state.lastMove = 0
	state.direction = DIRECTION_RIGHT
	state.speed = 0.1
	state.length = 8
	state.level = 1
	state.gameOver = false
	newfood()
end

local function drawsnake()
	local n = #state.snake
	for k, v in ipairs(state.snake) do
		local c = k / n * 100
		love.graphics.setColor(255 - c, 255 - c, 255 - c)
		love.graphics.rectangle('fill', (v.x - 1) * BLOCKSIZE, (v.y - 1) * BLOCKSIZE, BLOCKSIZE, BLOCKSIZE)
	end
end

local font = {}
setmetatable(font, {__index = function(t, k)
	if rawget(t, k) == nil then
		t[k] = love.graphics.newFont(k)
	end

	return rawget(t, k)
end})

function love.load()
	-- preload fonts
	do
		local f = font
		local _ = f[10], f[16], f[24], f[48]
	end

	math.randomseed(os.time())
	math.random()

	reset()
end

function love.draw()
	for y=1, HEIGHT do
		for x=1, WIDTH do
			if (x + y) % 2 == 0 then
				love.graphics.setColor(30, 30, 30)
			else
				love.graphics.setColor(20, 20, 20)
			end

			local block = state.board[xy(x, y)]
			if block and block.type == BLOCK_FOOD then
				love.graphics.setColor(255, 0, 0)
			end

			love.graphics.rectangle('fill', (x - 1) * BLOCKSIZE, (y - 1) * BLOCKSIZE, BLOCKSIZE, BLOCKSIZE)

			if block and block.ttl then
				love.graphics.setColor(255, 255, 255)

				local s = ('%d'):format(block.ttl)
				love.graphics.print(s, 6 + (x - 1) * BLOCKSIZE, 3 + (y - 1) * BLOCKSIZE)
			end
		end
	end

	drawsnake()

	love.graphics.setFont(font[10])
	love.graphics.setColor(255, 255, 255)
	love.graphics.print('Level '..state.level, 10, 10)

	if state.gameOver then
		love.graphics.setFont(font[48])

		love.graphics.setColor(255, 200, 0)
		local s = 'GAME OVER'
		love.graphics.print(s, ((SCREEN_WIDTH / 2) - (font[48]:getWidth(s) / 2)), 200)

		love.graphics.setFont(font[16])
		s = 'Press R to restart'
		love.graphics.print(s, ((SCREEN_WIDTH / 2) - (font[16]:getWidth(s) / 2)), 400)
	end
end

local function collision()
	state.gameOver = true
end

function love.update(dt)
	if state.gameOver then return end

	-- fade blocks
	local toRemove = {}
	for k, v in pairs(state.board) do
		if v.ttl then
			v.ttl = v.ttl - dt
			if v.ttl < 0 then
				toRemove[#toRemove+1] = k
			end
		end
	end

	for k, v in ipairs(toRemove) do
		if state.board[v].type == BLOCK_FOOD then
			newfood()
		end

		state.board[v] = nil
	end

	-- only move every state.speed seconds
	state.lastMove = state.lastMove + dt
	if state.lastMove >= state.speed then
		state.lastMove = 0
	else
		return
	end

	local x, y
	local last = state.snake[#state.snake]

	-- calculate new position
	if state.direction == DIRECTION_RIGHT then
		x = last.x + 1
		y = last.y
	elseif state.direction == DIRECTION_LEFT then
		x = last.x - 1
		y = last.y
	elseif state.direction == DIRECTION_UP then
		x = last.x
		y = last.y - 1
	elseif state.direction == DIRECTION_DOWN then
		x = last.x
		y = last.y + 1
	end

	-- change these if you want to collide with walls
	if x > WIDTH then
		x = 1
	elseif x < 1 then
		x = WIDTH
	end

	if y > HEIGHT then
		y = 1
	elseif y < 1 then
		y = HEIGHT
	end

	-- limit length of snake
	while #state.snake > state.length do
		table.remove(state.snake, 1)
	end

	-- check self collision
	for k, v in ipairs(state.snake) do
		if x == v.x and y == v.y then
			collision()
			return
		end
	end

	-- check food collision
	local block = state.board[xy(x, y)]
	if block and block.type == BLOCK_FOOD then
		state.length = state.length * LEVEL_LENGTH_MULT
		state.board[xy(x, y)] = nil
		newfood()
		state.level = state.level + 1
	elseif block and block.type == BLOCK_WALL then
		collision()
		return
	end

	-- add new snake bit
	state.snake[#state.snake+1] = {x = x, y = y}

	state.lastDirection = state.direction
end

function love.keypressed(key, code)
	if state.gameOver then
		if key == 'r' then
			reset()
		end
	else
		local d = state.lastDirection or state.direction

		if key == 'up' and d ~= DIRECTION_DOWN then
			state.direction = DIRECTION_UP
		elseif key == 'down' and d ~= DIRECTION_UP then
			state.direction = DIRECTION_DOWN
		elseif key == 'left' and d ~= DIRECTION_RIGHT then
			state.direction = DIRECTION_LEFT
		elseif key == 'right' and d ~= DIRECTION_LEFT then
			state.direction = DIRECTION_RIGHT
		end
	end
end
User avatar
BlackBulletIV
Inner party member
Posts: 1261
Joined: Wed Dec 29, 2010 8:19 pm
Location: Queensland, Australia
Contact:

Re: Snake

Post by BlackBulletIV »

Nice little game you've got there. Very simple, but it's good. Keep it up!
User avatar
Robin
The Omniscient
Posts: 6506
Joined: Fri Feb 20, 2009 4:29 pm
Location: The Netherlands
Contact:

Re: Snake

Post by Robin »

Nice, simple, I like it! :D

And here's a .love of it, to make it easier to play.
Attachments
snake.love
(1.81 KiB) Downloaded 325 times
Help us help you: attach a .love.
User avatar
BlackBulletIV
Inner party member
Posts: 1261
Joined: Wed Dec 29, 2010 8:19 pm
Location: Queensland, Australia
Contact:

Re: Snake

Post by BlackBulletIV »

Ah yes, a .love file always makes things easier.

By the way Robin, I just had a look at the thing in your signature. It's pretty darn funny! Captures so much of the inside Love stuff.
User avatar
Robin
The Omniscient
Posts: 6506
Joined: Fri Feb 20, 2009 4:29 pm
Location: The Netherlands
Contact:

Re: Snake

Post by Robin »

BlackBulletIV wrote:By the way Robin, I just had a look at the thing in your signature. It's pretty darn funny! Captures so much of the inside Love stuff.
Thanks, glad you liked it! :)
Help us help you: attach a .love.
User avatar
asurakyo
Prole
Posts: 8
Joined: Tue Mar 01, 2011 6:30 am

Re: Snake

Post by asurakyo »

It's nice little game...wow... :crazy:
obur
Prole
Posts: 11
Joined: Sun Feb 20, 2011 2:03 pm

Re: Snake

Post by obur »

this is awesome! wow. thanks for making me feel stupid and worthless :P
User avatar
crow
Party member
Posts: 186
Joined: Thu Feb 24, 2011 11:47 pm
Location: UK
Contact:

Re: Snake

Post by crow »

Hmm did this user get lost somewhere or forget there login ? they not been been back since or at lest not posted under this username :monocle:
Sir Kittenface
Möko IDE Codename (Erös) Returns Soon

I am dyslexic so if any of my replys confusing please just ask me to reword it as this will make things a lot easier for all parties lol.
User avatar
bartbes
Sex machine
Posts: 4946
Joined: Fri Aug 29, 2008 10:35 am
Location: The Netherlands
Contact:

Re: Snake

Post by bartbes »

He's still in irc.
User avatar
crow
Party member
Posts: 186
Joined: Thu Feb 24, 2011 11:47 pm
Location: UK
Contact:

Re: Snake

Post by crow »

bartbes wrote:He's still in irc.
I guess IRC is a easier place ... hang on a picking min how did I miss the IRC that will be something I been joining later todoy/tomorrow lol :megagrin:
Sir Kittenface
Möko IDE Codename (Erös) Returns Soon

I am dyslexic so if any of my replys confusing please just ask me to reword it as this will make things a lot easier for all parties lol.
Post Reply

Who is online

Users browsing this forum: No registered users and 0 guests