Skip to content

Commit

Permalink
Merge pull request #32 from mkli90/enhancement/31-make-the-player-app…
Browse files Browse the repository at this point in the history
…ear-on-the-screen

#31 - Character is appearing on the screen
  • Loading branch information
Max K. authored and Max K. committed May 7, 2015
2 parents 90ee738 + b788b23 commit 919c593
Show file tree
Hide file tree
Showing 17 changed files with 353 additions and 114 deletions.
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
language: python
python:
- "3.4"
- "2.7"
sudo: required
install:
- sudo apt-get update -qq
Expand Down
File renamed without changes
Binary file added assets/player/player.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 2 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ python-coveralls==2.5.0
tazlib==1.2.0
pytmx==3.20.9
pyscroll==2.14.2
hg+http://bitbucket.org/pygame/pygame
hg+http://bitbucket.org/pygame/pygame
mock==1.0.1
5 changes: 3 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

setup(name="tekmate",
version="0.0.1",
description="Tekmate - Stargate-Based RPG",
description="Tekmate - Stargate-Based Point'n'Click",
author="Max",
packages=['tekmate'],
license="GPLv3",
Expand All @@ -18,7 +18,8 @@
"License :: OSI Approved :: GNU General Public License v3 (GPLv3)",
"Natural Language :: English",
"Programming Language :: Python :: 3.4",
"Programming Language :: Python :: 2.7",
"Topic :: Games/Entertainment",
"Topic :: Software Development :: Libraries",
],
)
)
1 change: 0 additions & 1 deletion tekmate/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +0,0 @@
__author__ = 'max'
4 changes: 3 additions & 1 deletion tekmate/__main__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# -*- encoding: utf-8 -*-
from tekmate.game import PyGameInitializer, TekmateFactory

from tekmate.configuration import PyGameInitializer, TekmateFactory


def main():
Expand All @@ -8,5 +9,6 @@ def main():
game = game_factory.create()
game.enter_mainloop()


if __name__ == "__main__":
main()
68 changes: 68 additions & 0 deletions tekmate/configuration.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# -*- encoding: utf-8 -*-
from glob import glob

from os.path import join, splitext
import pygame
from taz.game import Game

from tekmate.scenes import WorldScene


class PyGameInitializer(object):
CAPTION = "Tek'ma'te"

def __init__(self, configuration):
self.configuration = configuration

def initialize(self):
pygame.init()
self.set_up_display()
self.set_up_mouse()
self.load_global_images()

return self.get_update_context(), self.get_render_context()

def set_up_display(self):
pygame.display.set_mode((self.configuration["display_width"], self.configuration["display_height"]))
pygame.display.set_caption(self.CAPTION)

def set_up_mouse(self):
pygame.mouse.set_visible(True)

def load_global_images(self):
images = dict()
base_path = join("assets", "global")
for image_file in glob(join(base_path, "*.png")):
name = splitext(image_file)
surface = pygame.image.load(join(base_path, image_file)).convert()
surface.set_colorkey((0, 128, 128))
images[name[0]] = surface
return images

def get_render_context(self):
render_context = {
"flip": pygame.display.flip,
"display": pygame.display.get_surface(),
"images-global": self.load_global_images()
}
return render_context

def get_update_context(self):
update_context = {
"clock": pygame.time.Clock(),
"get_events": pygame.event.get
}
return update_context


class TekmateFactory(object):
def __init__(self, pygame_initializer):
self.pygame_initializer = pygame_initializer

def create(self):
update_context, render_context = self.pygame_initializer.initialize()
game = Game(update_context, render_context)
scene = WorldScene("world")
game.register_new_scene(scene)
game.push_scene_on_stack("world")
return game
51 changes: 8 additions & 43 deletions tekmate/game.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
# -*- encoding: utf-8 -*-
from taz.game import Game
from tekmate.items import Item

import pygame
from tekmate.scenes import WorldScene
from tekmate.items import Item


class Player(object):
class NoSuchItem(Exception):
pass

def __init__(self):
self.position = (0, 0)
self.bag = []

def add_item(self, item):
Expand All @@ -31,42 +29,9 @@ def look_at(self, item1):
def use_item(self, item1):
return item1.get_use_message()


class PyGameInitializer(object):
CAPTION = "Tek'ma'te"

def __init__(self, configuration):
self.configuration = configuration

def initialize(self):
pygame.init()
pygame.display.set_mode((self.configuration["display_width"], self.configuration["display_height"]))
pygame.display.set_caption(self.CAPTION)
return self.get_update_context(), self.get_render_context()

def get_render_context(self):
render_context = {
"flip": pygame.display.flip,
"display": pygame.display.get_surface()
}
return render_context

def get_update_context(self):
update_context = {
"clock": pygame.time.Clock(),
"get_events": pygame.event.get
}
return update_context


class TekmateFactory(object):
def __init__(self, pygame_initializer):
self.pygame_initializer = pygame_initializer

def create(self):
update_context, render_context = self.pygame_initializer.initialize()
game = Game(update_context, render_context)
scene = WorldScene("world")
game.register_new_scene(scene)
game.push_scene_on_stack("world")
return game
def move_player(self, mouse_pos):
if mouse_pos[0] < self.position[0]:
x = -100
else:
x = 100
self.position = (self.position[0] + x, self.position[1])
23 changes: 19 additions & 4 deletions tekmate/scenes.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,32 @@
import pygame
from taz.game import Scene, Game

from tekmate.ui import PlayerUserInterface


class WorldScene(Scene):
def initialize_scene(self): # pragma: no cover
print("Initializing World")
def __init__(self, ident):
super(WorldScene, self).__init__(ident)
self.player_ui = None

def initialize_scene(self):
self.player_ui = PlayerUserInterface()

def update(self): # pragma: no cover
def update(self): # pragma: no cover (This is only because of all the branches, they will get tested eventually)
for event in self.game.update_context["get_events"]():
if event.type == pygame.QUIT or self.escape_key_pressed(event):
raise Game.GameExitException
elif self.left_mouse_button_pressed(event):
self.player_ui.player.move_player(event.pos)
else:
pass

def render(self): # pragma: no cover
print("Rendering World")
self.game.render_context["display"].fill((0, 0, 0))
self.player_ui.render()
self.player_ui.draw_player_to_display(self.game.render_context["display"])

pygame.display.flip()

def resume(self): # pragma: no cover
print("Resuming World")
Expand All @@ -28,3 +40,6 @@ def tear_down(self): # pragma: no cover

def escape_key_pressed(self, event):
return event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE

def left_mouse_button_pressed(self, event):
return event.type == pygame.MOUSEBUTTONDOWN and event.button == 1
57 changes: 57 additions & 0 deletions tekmate/ui.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# -*- encoding: utf-8 -*-
import sys

import os
from os.path import abspath, split, join
import pygame

from tekmate.game import Player


class PlayerUserInterface(object):
class ImageNotFound(Exception):
pass

SCALING_FACTOR = 2.8

def __init__(self):
self.player = None
self.global_images = None
self.surface = None
self.image = None
self.create_surface_and_image(PlayerUserInterface.SCALING_FACTOR)
self.player = Player()

def render(self):
self.surface.fill((255, 255, 255))
self.surface.blit(self.image, (0, 0))

def draw_player_to_display(self, display): # pragma: no cover
display.blit(self.surface, self.get_position())

def create_surface_and_image(self, factor):
self.create_surface_with_factor(factor)
self.create_image_with_factor(factor)

def create_surface_with_factor(self, factor):
surface_proportions = (round(factor * 50), round(factor * 100))
self.surface = pygame.Surface(surface_proportions)
self.surface.convert()
self.surface.set_colorkey((0, 128, 128))

def create_image_with_factor(self, factor):
self.image = self.load_image("player", "player.png")
img_proportions = (int(round(factor * self.image.get_width())), int(round(factor * self.image.get_height())))
self.image = pygame.transform.scale(self.image, img_proportions)

def load_image(self, folder, name_of_file):
pth = abspath(split(__file__)[0])
sys.path.append(abspath(join(pth, u"..")))
fullname = os.path.join(pth, "..", "assets", folder, name_of_file)
try:
return pygame.image.load(fullname)
except:
raise PlayerUserInterface.ImageNotFound

def get_position(self):
return self.player.position
1 change: 1 addition & 0 deletions tests/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# -*- encoding: utf-8 -*-
79 changes: 79 additions & 0 deletions tests/test_configuration.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# -*- encoding: utf-8 -*-
from unittest import TestCase

from mock import patch, Mock
import pygame

from tekmate.configuration import PyGameInitializer, TekmateFactory
from tekmate.scenes import WorldScene


class PyGameInitializerTestCase(TestCase):
def setUp(self):
self.conf = {"display_width": 640, "display_height": 480}
self.pygame_initializer = PyGameInitializer(self.conf)
self.pygame_patcher = patch("tekmate.configuration.pygame", spec=True)
self.pygame = self.pygame_patcher.start()
self.uc, self.rc = self.pygame_initializer.initialize()

def test_can_create_pygame_initializer(self):
self.assertIsNotNone(self.pygame_initializer.configuration)

def test_initialze_pygame_actually_initializes_pygame(self):
self.pygame.init.assert_called_with()

def test_initialize_pygame_sets_the_caption(self):
self.pygame.display.set_caption.assert_called_with(PyGameInitializer.CAPTION)

def test_initialize_pygame_sets_window_resoultion_correctly_from_conf(self):
self.pygame.display.set_mode.assert_called_with((640, 480))

def test_initialize_pygame_loads_global_images(self):
self.assertEqual(self.pygame_initializer.load_global_images(), self.rc["images-global"])

def test_when_initialize_mouse_is_getting_configured_correctly(self):
self.pygame.mouse.set_visible.assert_called_with(True)

def test_update_context_should_have_a_clock(self):
self.assertTrue(hasattr(self.uc["clock"], "tick"))

def test_update_context_should_have_get_event_reference(self):
self.assertIs(self.uc["get_events"], self.pygame.event.get)

def test_render_context_should_have_flip_function(self):
self.assertIs(self.rc["flip"], self.pygame.display.flip)

def test_render_context_should_main_surface_reference(self):
self.assertIs(self.rc["display"], self.pygame.display.get_surface())


class TekmateFactoryTestCase(TestCase):
def setUp(self):
mock_init = Mock(spec=PyGameInitializer)
mock_scene = Mock(spec=WorldScene)
mock_init.initialize.return_value = None, {}

self.set_up_display()

self.mock_init = mock_init
self.mock_scene = mock_scene

def set_up_display(self):
pygame.display.init()
pygame.display.set_mode((1, 1))

def assertSceneRegistered(self, identifier, class_type):
game = TekmateFactory(self.mock_init).create()
scene = game.registered_scenes[identifier]
self.assertIsInstance(scene, class_type)

def test_create_should_initialize_pygame(self):
TekmateFactory(self.mock_init).create()
self.mock_init.initialize.assert_called_with()

def test_create_should_add_world_scene_to_game(self):
self.assertSceneRegistered("world", WorldScene)

def test_create_should_push_world_scene_to_game(self):
game = TekmateFactory(self.mock_init).create()
self.assertEqual(game.get_name_of_top_scene(), "world")
Loading

0 comments on commit 919c593

Please sign in to comment.