A gamepad usage example
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
Pandemic_Pong/pong_game.py

186 lines
8.4 KiB

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
pong_game.py
Pandemic Pong Game Engine
"""
from random import random
from playsound import playsound
import pong_constants as pgc # Pong global constants
import pong_globalvars as pgv # Pong global variables
from pong_player import PongPlayer
from pong_object import PongObject
class PongGame:
def __init__(self):
self.state = pgc.STATE_WELCOME # State of game
self.delay = 100 # Automatically leave splash screen ...
self.p1_game = 0 # Results (reset)
self.p2_game = 0
def game_fsm(self, player1, player2):
"""Game engine state machine"""
if (player1.state & pgc.BTN_BASE3) > 0 or (player2.state & pgc.BTN_BASE3) > 0:
player1.state = 0 # Don't play me again
player2.state = 0
self.delay = 50 # Say good bye!
self.state = pgc.STATE_EXIT
if self.state == pgc.STATE_WELCOME:
self.delay = self.delay - 1
if self.delay < 1:
self.state = pgc.STATE_START
elif self.state == pgc.STATE_START: # Start new game
if (player1.state & pgc.BTN_BASE4) > 0 or (player2.state & pgc.BTN_BASE4) > 0: # [Start] pressed?
player1.reinit(10, pgv.GAMEAREA_MAX_Y/2-50, 0, 0)
player2.reinit(pgv.GAMEAREA_MAX_X-40, pgv.GAMEAREA_MAX_Y/2-50, 0, 0)
self.p1_game = 0
self.p2_game = 0
player1.score = 0
player2.score = 0
self.state = pgc.STATE_PLAY
elif self.state == pgc.STATE_PLAY: # Remain playing 'til 10 points
if player1.delay > 0: # Infectious time running?
player1.delay = player1.delay - 1 # Yap!
if player1.delay <= 0:
player1.color = pgc.COL_WHITE
player1.state = 0
if player2.delay > 0: # for both players ...
player2.delay = player2.delay - 1
if player2.delay <= 0:
player2.color = pgc.COL_WHITE
player2.state = 0
if player1.score > 9 or (player2.score > 9):
if player1.score > 9: # Figure out winner
self.p1_game = self.p1_game + 1 # & count game accordingly
else:
self.p2_game = self.p2_game + 1
self.delay = 100
self.state = pgc.STATE_GAMERESULTS
elif self.state == pgc.STATE_GAMERESULTS:
if self.delay == 90:
playsound(pgc.game_win)
self.delay = self.delay - 1
if self.delay < 1:
if (self.p1_game > 2) or (self.p2_game > 2): # Set won?
self.delay = 100
self.state = pgc.STATE_FINALRESULTS # Yap!
else:
player1.score = 0
player2.score = 0
player1.reinit(10, pgv.GAMEAREA_MAX_Y/2-50, 0, 0)
player2.reinit(pgv.GAMEAREA_MAX_X-40, pgv.GAMEAREA_MAX_Y/2-50, 0, 0)
self.state = pgc.STATE_PLAY # Nope, move on to next game
elif self.state == pgc.STATE_FINALRESULTS:
if self.delay == 90:
playsound(pgc.match_win)
self.delay = self.delay - 1
if self.delay < 1:
player1.state = 0
player2.state = 0
self.state = pgc.STATE_START # Continue by start button press
elif self.state == pgc.STATE_EXIT:
if self.delay == 40:
playsound(pgc.game_exit)
self.delay = self.delay - 1
if self.delay < 1:
return False
return True
def crashvectors(self, ball, player1, player2):
"""Collission detection"""
if ball.delta_x < 0: # Ball moves right->left (<----)
if (ball.x <= player1.x + player1.w) and (ball.x > player1.x): # Left player #1 in range?
if ball.y + ball.h >= player1.y: # Ball lower than player upper bound?
if ball.y <= player1.y + player1.h: # Ball higher than player lower bound?
if ball.color == pgc.COL_WHITE:
ball.color = player1.color # Pick up 'infection' (if any)
elif ball.color != player1.color: # Infectious ball!
return # w/o vaccine -> no save!
ball.delta_x = -ball.delta_x * 1.2 # Invert direction & speed up
if player1.delta_y > 0.0: # Going downwards
if ball.delta_y > 0.0: # As well?
ball.delta_y = ball.delta_y * 1.2 # Increase angle
else:
ball.delta_y = ball.delta_y * 0.8 # Decrease angle
elif player1.delta_y < 0.0:
if ball.delta_y < 0.0: # As well?
ball.delta_y = ball.delta_y * 1.2 # Increase angle
else:
ball.delta_y = ball.delta_y * 0.8 # Decrease angle
playsound(pgc.player_contact) # Enforce caching ...
else: # Ball moves left->right (---->)
if (ball.x + ball.w >= player2.x) and (ball.x < player2.x + player2.w): # Right player #2 in range?
if ball.y + ball.h >= player2.y: # Ball lower than player upper bound?
if ball.y <= player2.y + player2.h: # Ball higher than player lower bound?
if ball.color == pgc.COL_WHITE:
ball.color = player2.color # Pick up 'infection' (if any)
elif ball.color != player2.color: # Infectious ball!
return # w/o vaccine -> no save!
ball.delta_x = -ball.delta_x * 1.2 # Invert direction & speed up
if player2.delta_y > 0.0: # Going downwards
if ball.delta_y > 0.0: # As well?
ball.delta_y = ball.delta_y * 1.2 # Increase angle
else:
ball.delta_y = ball.delta_y * 0.8 # Decrease angle
elif player2.delta_y < 0.0:
if ball.delta_y < 0.0: # As well?
ball.delta_y = ball.delta_y * 1.2 # Increase angle
else:
ball.delta_y = ball.delta_y * 0.8 # Decrease angle
playsound(pgc.player_contact) # Enforce caching ...
def pong_game(self, ball, player1, player2):
if self.game_fsm(player1, player2) == False: # Exit
return False
# 1. Retrieve user entries
bChanged = player1.eval_gamepad()
bChanged = player2.eval_gamepad()
if self.state == pgc.STATE_PLAY: # Actually playing?
# 2. Adjust player positions
bChanged = player1.eval_position(pgv.GAMEAREA_MIN_X, pgv.GAMEAREA_MAX_X/2-50)
bChanged = player2.eval_position(pgv.GAMEAREA_MAX_X/2+50, pgv.GAMEAREA_MAX_X)
# 3. Crash analyses
self.crashvectors(ball, player1, player2)
# 4. Adjust object positions (ball & potentially others ...)
rc = ball.eval_object()
if rc != 0: # Miss left(-1) or right(1)
if rc == -1: # Player #2: +1
player2.score = player2.score + 1
ball.reinit(8 + (random() - 0.5) * 4, (random() - 0.5) * 10)
playsound(pgc.player_miss)
else: # Player #1: +1
player1.score = player1.score + 1
ball.reinit(-(8 + (random() - 0.5) * 4), (random() - 0.5) * 10)
playsound(pgc.player_miss)
return True
if __name__ == "__main__":
print("pong_game has no function, call 'pandemic_pong.py'")