summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--Game.py68
-rw-r--r--GameView.py56
-rw-r--r--Snake.py23
-rw-r--r--Vec.py23
-rwxr-xr-xmain.py44
6 files changed, 215 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..bee8a64
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+__pycache__
diff --git a/Game.py b/Game.py
new file mode 100644
index 0000000..07150e0
--- /dev/null
+++ b/Game.py
@@ -0,0 +1,68 @@
+
+from Snake import Snake
+from Vec import Vec2
+
+class Walls:
+ """Contains the walls of a game.
+ Supports iterating over the walls and checking if there is a wall at a specific coordinate.
+ Useful as a wrapper to later increase performance of these operations."""
+
+ _walls = []
+
+ def __init__(self, walls):
+ self._walls = walls
+
+ def fromString(wallString):
+ walls = []
+ y = 0
+ for line in wallString.split('\n'):
+ x = 0
+ for char in line:
+ if char == "#":
+ walls.append(Vec2(x, y))
+ x += 1
+ y += 1
+ return Walls(walls)
+
+ def walls(self):
+ return self._walls
+
+ def wallAt(self, pos):
+ return (pos in self._walls)
+
+ def width(self):
+ return max(self._walls, key=lambda p: p.x).x + 1
+
+ def height(self):
+ return max(self._walls, key=lambda p: p.y).y + 1
+
+
+class Game:
+ """Class responsible for the main logic of a game.
+ For a game, this will probably be a singleton."""
+
+ snake = Snake([Vec2(6, 6), Vec2(6, 7), Vec2(6,8), Vec2(7,8)])
+ walls = Walls.fromString("""###############
+# #
+# #
+# #
+# #
+# #
+# #
+# #
+# #
+# #
+# #
+# ### #
+# #
+###############""")
+
+ def width(self): return self.walls.width()
+ def height(self): return self.walls.height()
+
+ def tick(self):
+ self.snake.move()
+
+ def isLost(self):
+ return self.snake.headInTail() or self.walls.wallAt(self.snake.head())
+
diff --git a/GameView.py b/GameView.py
new file mode 100644
index 0000000..241914c
--- /dev/null
+++ b/GameView.py
@@ -0,0 +1,56 @@
+
+from Game import Game
+import pygame
+
+class GameView:
+
+
+ game = Game()
+
+ cellWidth = 64
+
+ _tickTime = 700
+
+ _previousTick = None
+
+ nextControlDirection = None
+
+
+ def isRunning(self): return not self.game.isLost()
+
+
+ def width(self): return self.game.width() * self.cellWidth
+
+
+ def height(self): return self.game.height() * self.cellWidth
+
+
+ def render(self, surface):
+
+ surface.fill("black")
+
+ for cell in self.game.snake.cells:
+ pygame.draw.rect(surface, "red", pygame.Rect(
+ cell.x*self.cellWidth,
+ cell.y*self.cellWidth,
+ self.cellWidth,
+ self.cellWidth
+ ))
+
+ for cell in self.game.walls.walls():
+ pygame.draw.rect(surface, "white", pygame.Rect(
+ cell.x*self.cellWidth,
+ cell.y*self.cellWidth,
+ self.cellWidth,
+ self.cellWidth
+ ))
+
+
+ def update(self, time):
+ if (self._previousTick == None) or (self._previousTick + self._tickTime <= time):
+ self._previousTick = time
+ if self.nextControlDirection != None:
+ self.game.snake.heading = self.nextControlDirection
+ self.nextControlDirection = None
+ self.game.tick()
+
diff --git a/Snake.py b/Snake.py
new file mode 100644
index 0000000..81c3b0b
--- /dev/null
+++ b/Snake.py
@@ -0,0 +1,23 @@
+
+import Vec
+
+class Snake:
+
+ cells = []
+ heading = Vec.up
+
+ def __init__(self, cells):
+ self.cells = cells
+
+ def move(self):
+ self.cells.pop()
+ self.cells.insert(0, self.cells[0] + self.heading)
+
+ def headInTail(self):
+ res = False
+ for i in range(1, len(self.cells)):
+ res = res or (self.cells[0] == self.cells[i])
+ return res
+
+ def head(self):
+ return self.cells[0]
diff --git a/Vec.py b/Vec.py
new file mode 100644
index 0000000..9f22dd0
--- /dev/null
+++ b/Vec.py
@@ -0,0 +1,23 @@
+
+class Vec2:
+
+ x = 0
+ y = 0
+
+ def __init__(self, x, y):
+ self.x = x
+ self.y = y
+
+ def __add__(self, other):
+ return Vec2(self.x + other.x, self.y + other.y)
+
+ def __eq__(self, other):
+ return (other != None) and (self.x == other.x) and (self.y == other.y)
+
+ def neg(self):
+ return Vec2(-self.x, -self.y)
+
+right = Vec2(1, 0)
+up = Vec2(0, -1)
+left = Vec2(-1, 0)
+down = Vec2(0, 1)
diff --git a/main.py b/main.py
new file mode 100755
index 0000000..52063f7
--- /dev/null
+++ b/main.py
@@ -0,0 +1,44 @@
+#!/bin/python
+
+import pygame
+import Vec
+from GameView import GameView
+
+
+view = GameView()
+
+nextControlDirection = None
+pygame.init
+screen = pygame.display.set_mode((view.width(), view.height()))
+clock = pygame.time.Clock()
+running = True
+
+while running:
+
+ for event in pygame.event.get():
+ if event.type == pygame.QUIT:
+ running = False
+
+ keys = pygame.key.get_pressed()
+ if keys[pygame.K_w] and view.game.snake.heading != Vec.up.neg():
+ view.nextControlDirection = Vec.up
+ elif keys[pygame.K_a] and view.game.snake.heading != Vec.left.neg():
+ view.nextControlDirection = Vec.left
+ elif keys[pygame.K_r] and view.game.snake.heading != Vec.down.neg():
+ view.nextControlDirection = Vec.down
+ elif keys[pygame.K_s] and view.game.snake.heading != Vec.right.neg():
+ view.nextControlDirection = Vec.right
+
+ if view.isRunning():
+ view.update(pygame.time.get_ticks())
+
+ # fill the screen with a color to wipe away anything from last frame
+ screen.fill("purple")
+
+ view.render(screen)
+
+ pygame.display.flip()
+
+ clock.tick(60) # limits FPS to 60
+
+pygame.quit()