snakeware

Python-based Linux distro for x86-64 and RPi
git clone git://squid-tech.com/snakeware.git
Log | Files | Refs | README

commit 1900e23f46d19a095f73b759e8dd688d37afe0e4
parent ee97803b4346fbfc31bd32243defea86c36efefd
Author: Josh Moore <jxm5210@g.rit.edu>
Date:   Sun, 31 May 2020 17:14:43 -0400

Merge pull request #32 from joshiemoore/snake-games

Snake games
Diffstat:
M.gitignore | 5+++--
Asnake_games/README.md | 67+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asnake_games/__init__.py | 5+++++
Asnake_games/circlez/__init__.py | 4++++
Asnake_games/circlez/circ.py | 62++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asnake_games/gamemenu.py | 79+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asnake_games/snake/README.txt | 3+++
Asnake_games/snake/__init__.py | 6++++++
Asnake_games/snake/sgame.py | 186+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msnakeware/post-build.sh | 4++++
10 files changed, 419 insertions(+), 2 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -1,3 +1,5 @@ *.swp venv/ -.idea/- \ No newline at end of file +.idea/ + +__pycache__/ diff --git a/snake_games/README.md b/snake_games/README.md @@ -0,0 +1,67 @@ +# snake_games + +This is the user-made games repository for snakeware. These games come shipped +standard with every snakeware release. We are only going to include fun free +games made by amateurs here. + +To run these games, boot into snakeware and enter these commands: + +``` +>>> import snake_games +>>> snake_games.menu() +``` + +This will launch an interactive menu where you can select a game to play. Also, +if you already know the name of the game you want, you can import and run it +directly like this: + +``` +>>> import snake_games.snake +>>> snake_games.snake.load() +``` + +## Contributing + +If you would like to include your game in snake_games, please send a PR adding +it to this directory! However, it's important to note that you will need to +make some changes to your game before it will run in the snakeware environment. +PRs will be approved if they meet the following guidelines: + +* Your game must be written in Python. + +* Your game must have an `__init__.py` with a `load()` function which creates +an instance of your game and launches it. Please see existing games in this +directory for examples of how this works. + +* Your game must be fullscreen, and it must draw directly to the framebuffer. +You can set pygame to fbdev mode by adding `os.putenv('SDL_FBDEV', '/dev/fb0')` +right before your call to `pygame.display.init()`. + +* You should not try to set the dimensions of the pygame window, but should +instead get the dimensions of the full-screen display after calling +`pygame.display.init()` like so: + +``` +DIMS = ( + pygame.display.Info().current_w, + pygame.display.Info().current_h +) +``` +You should write your game so that it handles these varying screen dimensions +gracefully. + +* Your game must have a way for the user to immediately exit and return to +snakeware at any time, preferably by pressing the `ESC` key. + +* Please test your game before submitting a PR. At minimum, you should try +launching your game as root from a different TTY to verify that your game works +as expected without X Windows running. + +Feel free to reach out if you have any questions while you're modifying your +game to run on snakeware! + +Also, your game does not have to be based on pygame. We will accept other +libraries as long as they allow you to draw directly to the framebuffer, and +your game meets the above guidelines. + +We would be happy to accept text-based/console games as well! diff --git a/snake_games/__init__.py b/snake_games/__init__.py @@ -0,0 +1,5 @@ + +def menu(): + from .gamemenu import SnakeGameMenu + + SnakeGameMenu().menu() diff --git a/snake_games/circlez/__init__.py b/snake_games/circlez/__init__.py @@ -0,0 +1,4 @@ +from .circ import CirclezApp + +def load(): + CirclezApp().run() diff --git a/snake_games/circlez/circ.py b/snake_games/circlez/circ.py @@ -0,0 +1,62 @@ +""" +A simple little demo app for snakeware, it draws circles. + +Josh Moore 2020 +""" + +import pygame + +import random +import os + +class CirclezApp: + def __init__(self): + pygame.init() + + # set pygame to fbdev mode + os.putenv('SDL_FBDEV', '/dev/fb0') + pygame.display.init() + + # get screen dimensions + self.DIMS = ( + pygame.display.Info().current_w, + pygame.display.Info().current_h + ) + + # init screen + self.SCREEN = pygame.display.set_mode( + self.DIMS, + pygame.FULLSCREEN + ) + + # init background + self.BG = pygame.Surface((self.DIMS)) + self.BG.fill((0,0,0)) + + pygame.mouse.set_visible(False) + pygame.display.update() + + def run(self): + clock = pygame.time.Clock() + + while True: + for event in pygame.event.get(): + if event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE: + exit() + + pygame.draw.circle( + self.BG, + ( + random.randint(0, 255), + random.randint(0, 255), + random.randint(0, 255) + ), + ( + random.randint(0, self.DIMS[0]), + random.randint(0, self.DIMS[1]) + ), + random.randint(10, 100) + ) + self.SCREEN.blit(self.BG, (0,0)) + pygame.display.flip() + clock.tick(30) diff --git a/snake_games/gamemenu.py b/snake_games/gamemenu.py @@ -0,0 +1,79 @@ +import os +import importlib + +class SnakeGameMenu(): + GAMENUMS = '0123456789' + + def __init__(self): + self.GAMEPATH = os.path.dirname(os.path.abspath(__file__)) + self.LIST = [] + self.cur_page = 0 + + for file in os.listdir(self.GAMEPATH): + if os.path.isdir(self.GAMEPATH + '/' + file) and\ + os.path.isfile(self.GAMEPATH + '/' + file + '/__init__.py'): + self.LIST.append(file) + + def list_page(self): + """ + List all of the games on the current page. + """ + page_idx = self.cur_page * 10 + + for i in range(10): + if i + page_idx >= len(self.LIST): + break + print(' ' + str(i) + '. ' + self.LIST[i + page_idx]) + print('') + + def list_games(self): + """ + Render the full current page for the games list, including the + header and prompt for user input. + """ + os.system('clear') + + print('\n\n~~~~~ SNAKE GAMES ~~~~~\n') + print(' Page {0}/{1}:'.format( + self.cur_page + 1, + int(len(self.LIST) / 10 + 1) + )) + + self.list_page() + + print(' 0-9: Select Game') + print(' + : Next Page') + print(' - : Prev Page') + print(' q : Quit\n') + + resp = input(' >') + + if resp == 'q': + # quit + exit() + elif resp == '+': + # next page + if self.cur_page < int(len(self.LIST) / 10): + self.cur_page = self.cur_page + 1 + elif resp == '-': + # prev page + if self.cur_page > 0: + self.cur_page = self.cur_page - 1 + elif len(resp) == 1 and resp in self.GAMENUMS: + # load selected game + sidx = self.cur_page * 10 + int(resp) + + if sidx >= len(self.LIST): + return + + print('Loading ' + self.LIST[sidx] + '...') + + game = 'snake_games.' + self.LIST[sidx] + _game = importlib.import_module(game) + _game.load() + + exit() + + def menu(self): + while True: + self.list_games() diff --git a/snake_games/snake/README.txt b/snake_games/snake/README.txt @@ -0,0 +1,3 @@ +Snake game shamelessly copied from https://pythonspot.com/snake-with-pygame/ +and adapated to work on snakeware. Please let me know if you would like it +removed from the distro. diff --git a/snake_games/snake/__init__.py b/snake_games/snake/__init__.py @@ -0,0 +1,6 @@ +from .sgame import SnakeApp + +def load(): + app = SnakeApp() + app.on_execute() + del app diff --git a/snake_games/snake/sgame.py b/snake_games/snake/sgame.py @@ -0,0 +1,186 @@ +from pygame.locals import * +from random import randint +import pygame +import time +import os + +class Apple: + x = 0 + y = 0 + step = 44 + + def __init__(self,x,y): + self.x = x * self.step + self.y = y * self.step + + def draw(self, surface): + pygame.draw.rect(surface, (0,255,0), (self.x,self.y, 44, 44), 0) + +class Player: + x = [0] + y = [0] + step = 44 + direction = 0 + length = 3 + + updateCountMax = 2 + updateCount = 0 + + def __init__(self, length): + self.length = length + for i in range(0,2000): + self.x.append(-100) + self.y.append(-100) + + # initial positions, no collision. + self.x[1] = 1*44 + self.x[2] = 2*44 + + def update(self): + + self.updateCount = self.updateCount + 1 + if self.updateCount > self.updateCountMax: + + # update previous positions + for i in range(self.length-1,0,-1): + self.x[i] = self.x[i-1] + self.y[i] = self.y[i-1] + + # update position of head of snake + if self.direction == 0: + self.x[0] = self.x[0] + self.step + if self.direction == 1: + self.x[0] = self.x[0] - self.step + if self.direction == 2: + self.y[0] = self.y[0] - self.step + if self.direction == 3: + self.y[0] = self.y[0] + self.step + + self.updateCount = 0 + + + def moveRight(self): + self.direction = 0 + + def moveLeft(self): + self.direction = 1 + + def moveUp(self): + self.direction = 2 + + def moveDown(self): + self.direction = 3 + + def draw(self, surface): + for i in range(0,self.length): + pygame.draw.rect(surface, (255,0,0), (self.x[i],self.y[i], 44,44), 0) + +class Game: + def isCollision(self,x1,y1,x2,y2,bsize): + if x1 >= x2 and x1 <= x2 + bsize: + if y1 >= y2 and y1 <= y2 + bsize: + return True + return False + +class SnakeApp: + player = 0 + apple = 0 + + def __init__(self): + self._running = True + self._display_surf = None + self._image_surf = None + self._apple_surf = None + self.game = Game() + self.player = Player(3) + self.apple = Apple(5,5) + + def on_init(self): + pygame.init() + + # initialize pygame to the framebuffer + os.putenv('SDL_FBDEV', '/dev/fb0') + pygame.display.init() + pygame.mouse.set_visible(False) + + self.DIMS = ( + pygame.display.Info().current_w, + pygame.display.Info().current_h + ) + + self._display_surf = pygame.display.set_mode( + self.DIMS, + pygame.FULLSCREEN + ) + + self._running = True + + def on_event(self, event): + if event.type == QUIT: + self._running = False + + def on_loop(self): + self.player.update() + + # does snake eat apple? + for i in range(0,self.player.length): + if self.game.isCollision(self.apple.x,self.apple.y,self.player.x[i], self.player.y[i],44): + self.apple.x = randint(2, int(self.DIMS[0] / 44) - 2) * 44 + self.apple.y = randint(2, int(self.DIMS[1] / 44) - 2) * 44 + self.player.length = self.player.length + 1 + + + # does snake collide with itself? + for i in range(2,self.player.length): + if self.game.isCollision(self.player.x[0],self.player.y[0],self.player.x[i], self.player.y[i],40): + print("You lose! Collision: ") + print("x[0] (" + str(self.player.x[0]) + "," + str(self.player.y[0]) + ")") + print("x[" + str(i) + "] (" + str(self.player.x[i]) + "," + str(self.player.y[i]) + ")") + self._running = False + + # is the snake out of bounds? + if self.player.x[0] < 0 or self.player.y[0] < 0 or\ + self.player.x[0] >= self.DIMS[0] or self.player.y[0] >= self.DIMS[1]: + print("You lose!") + self._running = False + + pass + + def on_render(self): + self._display_surf.fill((0,0,0)) + self.player.draw(self._display_surf) + self.apple.draw(self._display_surf) + pygame.display.flip() + + def on_cleanup(self): + pygame.quit() + exit(0) + + def on_execute(self): + if self.on_init() == False: + self._running = False + + while( self._running ): + pygame.event.pump() + keys = pygame.key.get_pressed() + + if (keys[K_RIGHT]): + self.player.moveRight() + + if (keys[K_LEFT]): + self.player.moveLeft() + + if (keys[K_UP]): + self.player.moveUp() + + if (keys[K_DOWN]): + self.player.moveDown() + + if (keys[K_ESCAPE]): + self._running = False + + self.on_loop() + self.on_render() + + time.sleep (50.0 / 1000.0); + self.on_cleanup() diff --git a/snakeware/post-build.sh b/snakeware/post-build.sh @@ -12,3 +12,7 @@ $SNAKEWARE/buildroot/output/target/usr/bin/python3 -m pip install -r $SNAKEWARE/ # copy snakewm rm -rf $SNAKEWARE/buildroot/output/target/usr/lib/$PYLIBVER/snakewm cp -r $SNAKEWARE/../snakewm $SNAKEWARE/buildroot/output/target/usr/lib/$PYLIBVER/ + +# copy snake-games +rm -rf $SNAKEWARE/buildroot/output/target/usr/lib/$PYLIBVER/snake_games +cp -r $SNAKEWARE/../snake_games $SNAKEWARE/buildroot/output/target/usr/lib/$PYLIBVER/