Blender Nibbles! ( aka python mis-use )


"""
Blender Nibbles
===============

I was trying to think of some mis-uses for the python in blender and 
then I remembered good old FastTracker had a nibbles game built in!
So here is the very buggy Nibbles clone for blender!

[email protected]

Instructions
============
Use the cursor keys to move

Known Bugs
==========
	- You cant collide with yourself!
	- You cant collide with the walls!
	
"""

import Blender
from Blender.BGL import *
from Blender import Draw
from Blender import Window
import threading
import time
from random import random, randint
from math import fabs, sqrt

UP = 0
DOWN = 1
LEFT = 2
RIGHT = 3

class Apple:
	def __init__(self, x, y):
		self.x, self.y = x, y	
		
	def draw(self):
		x6, y6 = int(self.x) * 6.0, int(self.y) * 6.0
		glVertex2i(x6 - 3, y6 - 3)
		glVertex2i(x6 - 3, y6 + 3)
		glVertex2i(x6 + 3, y6 + 3)
		glVertex2i(x6 + 3, y6 - 3)				
		

class TailSection:
	def __init__(self):
		self.x = 0.0
		self.y = 0.0
	
	def draw(self):
		x6, y6 = int(self.x) * 6.0, int(self.y) * 6.0
		glVertex2i(x6 - 3, y6 - 3)
		glVertex2i(x6 - 3, y6 + 3)
		glVertex2i(x6 + 3, y6 + 3)
		glVertex2i(x6 + 3, y6 - 3)				
		
				
				
class Player:
	def __init__(self, app):
		self.app = app
		self.x = 0
		self.y = 0
		self.direction = UP
		self.speed = .1
		self.tail = [TailSection()]
		self.length = 5
		
	def draw(self):
		glColor3f(1.0, 1.0, 1.0)
		glBegin(GL_QUADS)		
		for ts in self.tail:
			ts.draw()
		glEnd()
		
	def tick(self, a):
		hx, hy = self.tail[0].x, self.tail[0].y
		try:
			sx, sy = self.tail[1].x, self.tail[1].y
		except IndexError:
			sx, sy = 0, 0
		
		if self.direction == UP:
			hy += self.speed #* a
		elif self.direction == DOWN:
			hy -= self.speed #* a
		elif self.direction == LEFT:
			hx -= self.speed #* a
		elif self.direction == RIGHT:
			hx += self.speed #* a
			
		#if fabs(hx - sx) > 1 or fabs(hy - sy) > 1:
		dx, dy = hx - sx, hy - sy
		if sqrt(dx * dx + dy * dy) > 1:
			head = TailSection()
			head.x = hx
			head.y = hy
			self.tail.insert(0, head)
			
			for apple in self.app.apples:
				if apple.x == int(head.x) and apple.y == int(head.y):
					self.length += 2
					self.app.apples.remove(apple)
			
			if len(self.tail) > self.length:
				del self.tail[-1]
		else:
			self.tail[0].x = hx
			self.tail[0].y = hy
		

class Game:
	def __init__(self):
		self.player = Player(self)
		self.apples = []
		self.win_id = Window.GetAreaID()
		self.game_half_width, self.game_half_height = 20 , 20
		self.half_width = self.game_half_width * 6
		self.half_height = self.game_half_height * 6
	
	def start(self):
		print "start"
		self.last_time = time.time()
		Draw.Register(self.draw, self.event, None)
		
	def stop(self):
		Draw.Exit()
	
	def draw(self):
		glClearColor(0.0, 0.0, 0.0, 1.0)
		glClear(GL_COLOR_BUFFER_BIT)	
		
		win_width, win_height = Window.GetAreaSize()
		
		glTranslatef(win_width / 2, win_height / 2, 0.0)
	
		glColor3f(1.0, 1.0, 1.0)
		glBegin(GL_LINE_LOOP)
		glVertex2i(3 -self.half_width,3 -self.half_height)
		glVertex2i(3 -self.half_width,3 +self.half_height)
		glVertex2i(3 +self.half_width,3 +self.half_height)
		glVertex2i(3 +self.half_width,3 -self.half_height)
		glEnd()
		
		self.player.draw()
	
		glColor3f(0.0, 1.0, 0.0)
		glBegin(GL_QUADS)	
		for apple in self.apples:
			apple.draw()
		glEnd()
		
		Window.QAdd(self.win_id, Draw.TIMER0, 0, 1)
			
	def tick(self):
		new_time = time.time()
		d = new_time - self.last_time
		
		self.player.tick(d)
		self.last_time = new_time	
		
		if len(self.apples) < 5:
			if random() > 0.8:
				self.create_apple()
		
		Draw.Redraw()
		
	def create_apple(self):
		rx = randint(-self.game_half_width, self.game_half_width)
		ry = randint(-self.game_half_height, self.game_half_height)
		self.apples.append(Apple(rx, ry))
			
	def event(self, e, val):
		if e == Draw.ESCKEY:
			self.stop()
		elif e == Draw.TIMER0:
			self.tick()
			
		elif e == Draw.LEFTARROWKEY:
			self.player.direction = LEFT
		elif e == Draw.RIGHTARROWKEY:
			self.player.direction = RIGHT
		elif e == Draw.UPARROWKEY:
			self.player.direction = UP
		elif e == Draw.DOWNARROWKEY:
			self.player.direction = DOWN
			
if __name__ == '__main__':
	Game().start()

Aah! The memories. :smiley: A little buggy, as you say, but still nice fun.