Skip to content

Commit

Permalink
Various updates
Browse files Browse the repository at this point in the history
  • Loading branch information
richstokes committed Apr 11, 2020
1 parent 45841c5 commit 24a462d
Show file tree
Hide file tree
Showing 72 changed files with 158 additions and 70 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
__pycache__/*
.DS_Store
5 changes: 5 additions & 0 deletions .vscode/arduino.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"board": "esp8266:esp8266:huzzah",
"configuration": "xtal=80,vt=flash,exception=legacy,ssl=all,eesz=4M2M,ip=lm2f,dbg=Disabled,lvl=None____,wipe=none,baud=115200",
"port": "/dev/tty.SLAB_USBtoUART"
}
21 changes: 21 additions & 0 deletions .vscode/c_cpp_properties.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"configurations": [
{
"name": "Mac",
"includePath": [
"/Users/rich/Library/Arduino15/packages/esp8266/tools/**",
"/Users/rich/Library/Arduino15/packages/esp8266/hardware/esp8266/2.6.3/**"
],
"forcedInclude": [],
"macFrameworkPath": [
"/System/Library/Frameworks",
"/Library/Frameworks"
],
"intelliSenseMode": "clang-x64",
"compilerPath": "/usr/bin/clang",
"cStandard": "c11",
"cppStandard": "c++17"
}
],
"version": 4
}
11 changes: 11 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
Copyright 2020 richstokes et al

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ Inspired by Netflix's "[Chaos Monkey](https://github.com/Netflix/chaosmonkey)",
>CHAOS ENGINEERING IS:
>"the discipline of experimenting on a distributed system in order to build confidence in the system's capability to withstand turbulent conditions in production."
 

Kubernetes pods are represented by crates in the game. The more pods you have, the more crates are dropped!

You can control the monkey with the arrow keys, and punch crates with spacebar.
Expand Down
11 changes: 7 additions & 4 deletions constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,11 @@
# Will create (Actual number of running pods * CONTAINER_FACTOR) crates in game. Each crate represents one pod
CONTAINER_FACTOR = 0.4

# How many containers to spawn in offline mode
OFFLINE_CRATE_COUNT = 20

# Default friction used for sprites, unless otherwise specified
DEFAULT_FRICTION = 0.2
DEFAULT_FRICTION = 0.4

# Default mass used for sprites
DEFAULT_MASS = 1.2
Expand All @@ -19,16 +22,16 @@
GRAVITY = (0.0, -900.0)

# Player forces
PLAYER_FRICTION = 10
PLAYER_MOVE_FORCE = 700 # was 700
PLAYER_FRICTION = 0.5
PLAYER_MOVE_FORCE = 700
PLAYER_JUMP_IMPULSE = 600
PLAYER_PUNCH_IMPULSE = 1000

# Grid-size
SPRITE_SIZE = 64

# How close we get to the edge before scrolling
VIEWPORT_MARGIN = 120
VIEWPORT_MARGIN = 100

# Player textures
TEXTURE_LEFT = 0
Expand Down
16 changes: 9 additions & 7 deletions create_level.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ def decorate_clouds(sprite_list, count):
sprite.center_x = randint(-1500, 1500)
sprite_list.append(sprite)

def create_level_1(space, static_sprite_list, dynamic_sprite_list, bg_sprite_list):
def create_level_1(space, static_sprite_list, dynamic_sprite_list, bg_sprite_list, fg_sprite_list):
""" Create level one. """
create_floor(space, static_sprite_list)
create_walls(space, static_sprite_list)
Expand All @@ -173,15 +173,15 @@ def create_level_1(space, static_sprite_list, dynamic_sprite_list, bg_sprite_lis
# Add decorations
decorate_cactus(bg_sprite_list, 0, 96, 8) # Cacti along ground
decorate_cactus_large(bg_sprite_list, 0, 127, 3)
decorate_grass(bg_sprite_list, 0, 96, 20)
decorate_rock(bg_sprite_list, 0, 96, 3)
decorate_rock_small(bg_sprite_list, 0, 76, 10)
decorate_grass(bg_sprite_list, 0, 95, 20)
decorate_rock(bg_sprite_list, 0, 95, 3)
decorate_rock_small(fg_sprite_list, 0, 72, 10)
# decorate_clouds(bg_sprite_list, 10)

# Create the stacks of boxes based on number of running pods or create random ones if offline mode
# print(constants.OFFLINE_MODE)
if constants.OFFLINE_MODE == True:
CRATE_COUNT = 100
CRATE_COUNT = constants.OFFLINE_CRATE_COUNT
else:
logging.info("Attempting to connect to Kubernetes API host..")
try:
Expand All @@ -194,16 +194,18 @@ def create_level_1(space, static_sprite_list, dynamic_sprite_list, bg_sprite_lis

logging.info("Creating %s crates", int(CRATE_COUNT * constants.CONTAINER_FACTOR))

i = 0
# Create crates in random locations, based on number of pods * CONTAINER_FACTOR
i = 0
while i < int(CRATE_COUNT * constants.CONTAINER_FACTOR):
x = random.randrange(-1000, 2000)
y = random.randrange(200, 6000) # Drop crates in from random heights
# print(x)
# print(y)
sprite = PymunkSprite("./images/tiles/boxCrate_double.png", x, y, scale=0.5, friction=1.4)
sprite = PymunkSprite("./images/tiles/boxCrate_double.png", x, y, scale=constants.SPRITE_SCALING, friction=0.6)
dynamic_sprite_list.append(sprite)
space.add(sprite.body, sprite.shape)
# fall_sound = arcade.load_sound("./sounds/wooddrop.wav")
# arcade.play_sound(fall_sound)
i += 1

logging.info("Number of crates created: %s", len(dynamic_sprite_list))
88 changes: 56 additions & 32 deletions main_window.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import timeit
import os
import arcade
from pyglet.gl import GL_NEAREST
import pymunk
import logging
import math
Expand Down Expand Up @@ -61,7 +62,11 @@ def __init__(self, width, height, title):
# Lists of sprites
self.dynamic_sprite_list = arcade.SpriteList[PymunkSprite]()
self.static_sprite_list = arcade.SpriteList()
self.static_sprite_list.is_static = True
self.bg_sprite_list = arcade.SpriteList()
self.bg_sprite_list.is_static = True
self.fg_sprite_list = arcade.SpriteList()
self.fg_sprite_list.is_static = True

# Used for dragging shapes around with the mouse
self.shape_being_dragged = None
Expand Down Expand Up @@ -94,38 +99,47 @@ def __init__(self, width, height, title):
self.down_pressed = False
self.is_jumping = False

# Build the level
create_level_1(self.space, self.static_sprite_list, self.dynamic_sprite_list, self.bg_sprite_list)

def setup(self):
""" Set up the game and initialize the variables. """
# Build the level
create_level_1(self.space, self.static_sprite_list, self.dynamic_sprite_list, self.bg_sprite_list, self.fg_sprite_list)

# Set up the player
x = 50
y = (SPRITE_SIZE + SPRITE_SIZE / 2)
y = (SCREEN_HEIGHT / 2)
# self.player = Player("./images/tiles/grassMid.png", x, y, scale=0.5, moment=pymunk.inf, mass=1)
self.player = Player("./images/Char_Monkey_Free_Images/Animations/monkey_idle.png", x, y, scale=0.42, moment=pymunk.inf, mass=1)
self.player.center_x = SCREEN_WIDTH / 2
self.player.center_y = SCREEN_HEIGHT / 2
self.player = Player("./images/Char_Monkey_Free_Images/Animations/monkey_idle.png", x, y, scale=0.5, moment=pymunk.inf, mass=1)
# self.player.center_x = SCREEN_WIDTH / 2
# self.player.center_y = SCREEN_HEIGHT / 2
self.dynamic_sprite_list.append(self.player)
self.space.add(self.player.body, self.player.shape)
# logging.info("Number of dynamic sprites created: %s", len(self.dynamic_sprite_list))

# Load sounds
self.jump_sound = arcade.load_sound("./sounds/jump3.wav")
self.punch_sound = arcade.load_sound("./sounds/woodhit.wav")
self.explode_sound = arcade.load_sound("./sounds/432668__dxeyes__crate-break-4.wav")


def on_draw(self):
""" Render the screen. """
self.frame_count += 1

# This command has to happen before we start drawing
arcade.start_render()

# self.player.draw_hit_box(arcade.color.RED, 3) # Draw hitboxes for debugging

# print("Number of dynamic sprites present:", len(self.dynamic_sprite_list))

# Start timing how long this takes
draw_start_time = timeit.default_timer()

# Draw all the sprites
self.static_sprite_list.draw()
self.bg_sprite_list.draw()
self.dynamic_sprite_list.draw()
self.bg_sprite_list.draw(filter=GL_NEAREST)
self.static_sprite_list.draw(filter=GL_NEAREST)
self.dynamic_sprite_list.draw(filter=GL_NEAREST)
self.ball_sprite_list.draw()
self.fg_sprite_list.draw(filter=GL_NEAREST)

# Once per split second
if self.frame_count % 20 == 0:
Expand Down Expand Up @@ -245,31 +259,45 @@ def on_update(self, delta_time):

# Keep track of how long this function takes.
start_time = timeit.default_timer()

# print(self.player.scale)

# print(self.player.body.position)
# # Print key states for debugging
# logging.info("Left: %s", self.left_pressed)
# logging.info("Right: %s", self.right_pressed)
# logging.info("Up: %s", self.up_pressed)


# self.player.center_y = self.player.center_y + 6

# # Debug grounding
# grounding = check_grounding(self.player) # find out if player is standing on ground
# if grounding['body'] is not None:
# logging.info("Grounding: %s", grounding['normal'].x / grounding['normal'].y)
# logging.info("Player friction: %s", self.player.shape.friction)

# See if the player is standing on an item.
# If she is, apply opposite force to the item below her.
# So if she moves left, the box below her will have
# a force to move to the right.
grounding = check_grounding(self.player)
if self.force[0] and grounding and grounding['body']:
grounding['body'].apply_force_at_world_point((-self.force[0], 0), grounding['position'])

# Apply force to monkey if direction keys pressed
if self.up_pressed:
grounding = check_grounding(self.player) # find out if player is standing on ground
if grounding['body'] is not None and abs(
grounding['normal'].x / grounding['normal'].y) <= self.player.shape.friction and self.player.body.velocity[1] < 1:
# She is! Go ahead and jump
self.player.body.apply_impulse_at_local_point((0, PLAYER_JUMP_IMPULSE))
arcade.play_sound(self.jump_sound)
# else:
# # print("Not on ground, cant jump")
# pass
elif self.down_pressed and not self.up_pressed:
# logging.info("Pressed down, not currently doing anything")
# self.force = (0, 0)
# self.player.shape.friction = PLAYER_FRICTION * 10 # act as a brake?
pass
if self.left_pressed and not self.right_pressed:
# Add force to the player, and set the player friction to zero
Expand All @@ -282,42 +310,34 @@ def on_update(self, delta_time):
if not self.right_pressed and not self.left_pressed and not self.up_pressed:
#If no directions pressed, stop player
self.force = (0, 0)
self.player.shape.friction = PLAYER_FRICTION #was 15
self.player.shape.friction = PLAYER_FRICTION * 15 # Greatly increase friction so player stops instead of sliding

# print(self.force, self.player.shape.friction, self.player.body.velocity) # Debug physics

# If we have force to apply to the player (from hitting the arrow
# keys), apply it.
self.player.body.apply_force_at_local_point(self.force, (0, 0))

# Update player sprites
self.player.update(self.frame_count) # Pass in frame_count so we can decide which frame of animation to use

# check_collision(self.player)
# print(self.player.position)

# See if the player is standing on an item.
# If she is, apply opposite force to the item below her.
# So if she moves left, the box below her will have
# a force to move to the right.
grounding = check_grounding(self.player)
if self.force[0] and grounding and grounding['body']:
grounding['body'].apply_force_at_world_point((-self.force[0], 0), grounding['position'])

# Check sprites
for sprite in self.dynamic_sprite_list:
if sprite.shape.body.position.y < 0: # Check for sprites that fall off the screen.
# Remove sprites from physics space
self.space.remove(sprite.shape, sprite.shape.body)
# Remove sprites from physics list
sprite.remove_from_sprite_lists()
if sprite.shape.name == "Pymunk" and sprite.shape.HITCOUNT >= CONTAINER_HEALTH / 2: # Change texture if 50% damaged
if sprite.shape.name == "Pymunk" and sprite.shape.HITCOUNT >= CONTAINER_HEALTH / 2: # Change texture of crate if 50% damaged
broken_texture = arcade.load_texture("./images/tiles/boxCrate_single.png")
sprite.texture = broken_texture
# print("Damanged crate")
# if sprite.shape.name:
# print(sprite.shape.name)
if sprite.shape.name == "Pymunk" and sprite.shape.HITCOUNT >= CONTAINER_HEALTH: # Destroy container if hit 3 times
if sprite.shape.name == "Pymunk" and sprite.shape.HITCOUNT >= CONTAINER_HEALTH: # Destroy container if hit CONTAINER_HEALTH times
# logging.info("Destroying shape %s", sprite.shape)
sprite.remove_from_sprite_lists()
arcade.play_sound(self.explode_sound)
# Kill random pod!
delete_thread = threading.Thread(target=self.kill_pod)
delete_thread.start()
Expand Down Expand Up @@ -358,24 +378,27 @@ def on_update(self, delta_time):

def kill_pod(self):
''' Deletes pod on kubernetes, then removes crate sprite from game '''
P1, P2 = list_pods()
self.LAST_POD_KILLED = delete_pod(P1, P2)
if constants.OFFLINE_MODE == False:
P1, P2 = list_pods()
self.LAST_POD_KILLED = delete_pod(P1, P2)

# def delayed_remove(self, sprite):
# time.sleep(2)
# sprite.remove_from_sprite_lists()

def punch(self):
''' Punch a crate '''
# --- Punch left
# See if we have a physics object to our left
self.player.punching = True

check_point = (self.player.right + 20, self.player.center_y)
check_point = (self.player.right + 40, self.player.center_y)
shape_list = self.space.point_query(check_point, 1, pymunk.ShapeFilter())

# Apply force to any object to our left
for shape in shape_list:
# print(shape.shape.name)
arcade.play_sound(self.punch_sound)
shape.shape.body.apply_impulse_at_world_point((PLAYER_PUNCH_IMPULSE, PLAYER_PUNCH_IMPULSE),
check_point)
# Hit counter
Expand All @@ -384,11 +407,12 @@ def punch(self):

# --- Punch right
# See if we have a physics object to our left
check_point = (self.player.left - 20, self.player.center_y)
check_point = (self.player.left - 40, self.player.center_y)
shape_list = self.space.point_query(check_point, 1, pymunk.ShapeFilter())

# Apply force to any object to our right
for shape in shape_list:
arcade.play_sound(self.punch_sound)
shape.shape.body.apply_impulse_at_world_point((-PLAYER_PUNCH_IMPULSE, PLAYER_PUNCH_IMPULSE),
check_point)
# Hit counter
Expand Down
2 changes: 2 additions & 0 deletions physics_utility.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from constants import (
DEFAULT_FRICTION,
DEFAULT_MASS,
SPRITE_SCALING
)

import pymunk
Expand Down Expand Up @@ -37,6 +38,7 @@ def __init__(self,
self.shape.friction = friction
self.shape.HITCOUNT = 0
self.shape.name = "Pymunk"
self.scale = SPRITE_SCALING

def check_grounding(player):
""" See if the player is on the ground. Used to see if we can jump. """
Expand Down
Loading

0 comments on commit 24a462d

Please sign in to comment.