|
|
|
@ -14,29 +14,27 @@ import sys, os, fcntl, time
|
|
|
|
|
import os
|
|
|
|
|
import time
|
|
|
|
|
|
|
|
|
|
#from playsound import playsound
|
|
|
|
|
from playsound import playsound
|
|
|
|
|
|
|
|
|
|
from PyQt5.QtGui import (QPixmap, QPaintDevice, QImage, QMouseEvent, QColor)
|
|
|
|
|
from PyQt5.QtWidgets import *
|
|
|
|
|
from PyQt5.QtCore import Qt, QTimer, pyqtSlot, QEvent
|
|
|
|
|
from PyQt5.QtGui import QPainter, QBrush, QPen
|
|
|
|
|
from PyQt5.QtGui import QPainter, QBrush, QPen, QFont, QFontMetrics
|
|
|
|
|
|
|
|
|
|
import evalgamepad
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def crashvectors(ball, player1, player2):
|
|
|
|
|
if ball["delta_x"] < 0: # Ball moves right->left
|
|
|
|
|
if ball["x"] - ball["w"]/2 <= player1["x"] + player1["w"]: # Left player in range?
|
|
|
|
|
if ball["delta_x"] < 0: # Ball moves right->left (<----)
|
|
|
|
|
if ball["x"] <= player1["x"] + player1["w"]: # Left player in range?
|
|
|
|
|
if ball["y"] + ball["h"] >= player1["y"]: # Ball lower than player upper bound?
|
|
|
|
|
if ball["y"] - ball["h"]/2 <= player1["y"] + player1["h"]: # Ball higher than player lower bound?
|
|
|
|
|
ball["delta_x"] = -ball["delta_x"] # Invert direction
|
|
|
|
|
print("********************* PLAYER #1/BALL SAVED ********************")
|
|
|
|
|
else: # Ball moves left->right
|
|
|
|
|
if ball["x"] + ball["w"]/2 >= player2["x"]: # Right player in range?
|
|
|
|
|
if ball["y"] <= player1["y"] + player1["h"]: # Ball higher than player lower bound?
|
|
|
|
|
ball["delta_x"] = -ball["delta_x"]*1.2 # Invert direction
|
|
|
|
|
else: # Ball moves left->right (---->)
|
|
|
|
|
if ball["x"] + ball["w"] >= player2["x"]: # Right player in range?
|
|
|
|
|
if ball["y"] + ball["h"] >= player2["y"]: # Ball lower than player upper bound?
|
|
|
|
|
if ball["y"] - ball["h"]/2 <= player2["y"] + player2["h"]: # Ball higher than player lower bound?
|
|
|
|
|
ball["delta_x"] = -ball["delta_x"] # Invert direction
|
|
|
|
|
print("********************* PLAYER #2/BALL SAVED ********************")
|
|
|
|
|
if ball["y"] <= player2["y"] + player2["h"]: # Ball higher than player lower bound?
|
|
|
|
|
ball["delta_x"] = -ball["delta_x"]*1.2 # Invert direction
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def pong_game(ball, player1, player2):
|
|
|
|
@ -46,23 +44,23 @@ def pong_game(ball, player1, player2):
|
|
|
|
|
if (player1["state"] & evalgamepad.BTN_BASE4) > 0: # Exit?
|
|
|
|
|
print("Player #1 aborted game")
|
|
|
|
|
return False
|
|
|
|
|
else:
|
|
|
|
|
print("Player #1: {}h".format(hex(player1["state"])))
|
|
|
|
|
#else:
|
|
|
|
|
# print("Player #1: {}".format(hex(player1["state"])))
|
|
|
|
|
bChanged = evalgamepad.eval_gamepad(player2) # Exit?
|
|
|
|
|
if bChanged:
|
|
|
|
|
if (player2["state"] & evalgamepad.BTN_BASE4) > 0:
|
|
|
|
|
print("Player #2 aborted game")
|
|
|
|
|
return False
|
|
|
|
|
else:
|
|
|
|
|
print("Player #2: {}h".format(hex(player2["state"])))
|
|
|
|
|
#else:
|
|
|
|
|
# print("Player #2: {}".format(hex(player2["state"])))
|
|
|
|
|
|
|
|
|
|
# 2. Adjust player positions
|
|
|
|
|
bChanged = evalgamepad.eval_position(player1)
|
|
|
|
|
if bChanged:
|
|
|
|
|
print("Player #1: ", player1["x"], " / ", player1["y"])
|
|
|
|
|
#if bChanged:
|
|
|
|
|
# print("Player #1: ", player1["x"], " / ", player1["y"])
|
|
|
|
|
bChanged = evalgamepad.eval_position(player2)
|
|
|
|
|
if bChanged:
|
|
|
|
|
print("Player #2: ", player2["x"], " / ", player2["y"])
|
|
|
|
|
#if bChanged:
|
|
|
|
|
# print("Player #2: ", player2["x"], " / ", player2["y"])
|
|
|
|
|
|
|
|
|
|
# 3. Crash analyses
|
|
|
|
|
crashvectors(ball, player1, player2)
|
|
|
|
@ -74,15 +72,33 @@ def pong_game(ball, player1, player2):
|
|
|
|
|
print("***** Player #2: +1")
|
|
|
|
|
player2["score"] = player2["score"] + 1
|
|
|
|
|
evalgamepad.reinit_object(ball, 6, 2)
|
|
|
|
|
playsound('/usr/lib/libreoffice/share/gallery/sounds/laser.wav')
|
|
|
|
|
else:
|
|
|
|
|
print("***** Player #1: +1")
|
|
|
|
|
player1["score"] = player1["score"] + 1
|
|
|
|
|
evalgamepad.reinit_object(ball, -6, 2)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# use: playsound('/usr/lib/libreoffice/share/gallery/sounds/laser.wav')
|
|
|
|
|
playsound('/usr/lib/libreoffice/share/gallery/sounds/laser.wav')
|
|
|
|
|
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def draw_buttonstate(x, y, player, painter):
|
|
|
|
|
if (player["state"] & evalgamepad.BTN_TRIGGER) == evalgamepad.BTN_TRIGGER:
|
|
|
|
|
painter.setPen(QPen(Qt.blue, 1, Qt.SolidLine)) # Color/Linewidth/Pattern
|
|
|
|
|
painter.setBrush(QBrush(Qt.blue, Qt.SolidPattern)) # Fill
|
|
|
|
|
painter.drawEllipse(x, y, 20, 20) # Blue button
|
|
|
|
|
if (player["state"] & evalgamepad.BTN_TOP) == evalgamepad.BTN_TOP:
|
|
|
|
|
painter.setPen(QPen(Qt.green, 1, Qt.SolidLine)) # Green
|
|
|
|
|
painter.setBrush(QBrush(Qt.green, Qt.SolidPattern))
|
|
|
|
|
painter.drawEllipse(x + 30, y, 20, 20)
|
|
|
|
|
if (player["state"] & evalgamepad.BTN_THUMB) == evalgamepad.BTN_THUMB:
|
|
|
|
|
painter.setPen(QPen(Qt.red, 1, Qt.SolidLine)) # Red
|
|
|
|
|
painter.setBrush(QBrush(Qt.red, Qt.SolidPattern))
|
|
|
|
|
painter.drawEllipse(x + 60, y, 20, 20)
|
|
|
|
|
if (player["state"] & evalgamepad.BTN_THUMB2) == evalgamepad.BTN_THUMB2:
|
|
|
|
|
painter.setPen(QPen(Qt.yellow, 1, Qt.SolidLine)) # Yellow
|
|
|
|
|
painter.setBrush(QBrush(Qt.yellow, Qt.SolidPattern))
|
|
|
|
|
painter.drawEllipse(x + 90, y, 20, 20)
|
|
|
|
|
|
|
|
|
|
class pongWindow(QMainWindow):
|
|
|
|
|
def __init__(self):
|
|
|
|
|
super().__init__()
|
|
|
|
@ -97,8 +113,15 @@ class pongWindow(QMainWindow):
|
|
|
|
|
self.setWindowTitle(self.title)
|
|
|
|
|
self.setGeometry(self.top, self.left, self.width, self.height)
|
|
|
|
|
#self.showFullScreen()
|
|
|
|
|
self.pic = QPixmap("pictures/pong_background.png")
|
|
|
|
|
self.pic = QPixmap("pictures/pong_background.png")
|
|
|
|
|
# Font metrics assume font is monospaced!
|
|
|
|
|
self.fnt = QFont("Monospace",120)
|
|
|
|
|
self.fnt.setKerning(False)
|
|
|
|
|
self.fnt.setFixedPitch(True)
|
|
|
|
|
self.fm = QFontMetrics(self.fnt)
|
|
|
|
|
|
|
|
|
|
self.show()
|
|
|
|
|
playsound('/usr/lib/libreoffice/share/gallery/sounds/laser.wav') # Enforce caching ...
|
|
|
|
|
|
|
|
|
|
self.timer = QTimer() # Start processing 'loop'
|
|
|
|
|
self.timer.setInterval(25) # 25ms
|
|
|
|
@ -110,21 +133,31 @@ class pongWindow(QMainWindow):
|
|
|
|
|
global ball, player1, player2
|
|
|
|
|
|
|
|
|
|
painter = QPainter(self) # Painter need's to be freshly picked ...
|
|
|
|
|
painter.setPen(QPen(Qt.white, 1, Qt.SolidLine)) # Circle: Color/Linewidth/Pattern
|
|
|
|
|
painter.setPen(QPen(Qt.white, 1, Qt.SolidLine)) # Color/Linewidth/Pattern
|
|
|
|
|
painter.setBrush(QBrush(Qt.white, Qt.SolidPattern)) # Fill
|
|
|
|
|
|
|
|
|
|
painter.drawPixmap(self.rect(), self.pic) # Game background
|
|
|
|
|
|
|
|
|
|
painter.drawEllipse(int(ball["x"]), int(ball["y"]), 50, 50) # Ball
|
|
|
|
|
painter.drawRect(10, int(player1["y"]), 20, 100) # Player left
|
|
|
|
|
painter.drawRect(evalgamepad.GAMEAREA_MAX_X - 30, int(player2["y"]), 20, 100) # Player right
|
|
|
|
|
|
|
|
|
|
painter.drawText(10, 30, "X: {}".format(ball["x"]))
|
|
|
|
|
painter.drawText(10, 40, "y: {}".format(ball["y"]))
|
|
|
|
|
|
|
|
|
|
painter.drawText(200,40, "Player #1: {}".format(player1["score"]))
|
|
|
|
|
painter.drawText(evalgamepad.GAMEAREA_MAX_X-400,40, "Player #2: {}".format(player2["score"]))
|
|
|
|
|
painter.drawRect(int(ball["x"]), int(ball["y"]), int(ball["w"]), int(ball["h"])) # Ball
|
|
|
|
|
painter.drawRect(int(player1["x"]), int(player1["y"]), int(player1["w"]), int(player1["h"])) # Player left
|
|
|
|
|
painter.drawRect(int(player2["x"]), int(player2["y"]), int(player2["w"]), int(player2["h"])) # Player right
|
|
|
|
|
|
|
|
|
|
#painter.drawText(10, 30, "X: {}".format(ball["x"]))
|
|
|
|
|
#painter.drawText(10, 40, "y: {}".format(ball["y"]))
|
|
|
|
|
|
|
|
|
|
# Game scores
|
|
|
|
|
painter.setFont(self.fnt)
|
|
|
|
|
# Score player #1
|
|
|
|
|
msg = str(player1["score"])
|
|
|
|
|
msg_width = self.fm.width(msg)
|
|
|
|
|
painter.drawText(800 - msg_width, 154, "{}".format(player1["score"]))
|
|
|
|
|
# Score player #2
|
|
|
|
|
painter.drawText(evalgamepad.GAMEAREA_MAX_X-840, 154, "{}".format(player2["score"]))
|
|
|
|
|
|
|
|
|
|
# Indicate Button states
|
|
|
|
|
draw_buttonstate(60, 50, player1, painter)
|
|
|
|
|
draw_buttonstate(evalgamepad.GAMEAREA_MAX_X - 180, 50, player2, painter)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@pyqtSlot()
|
|
|
|
|
def on_timer(self):
|
|
|
|
@ -144,9 +177,9 @@ if __name__ == '__main__':
|
|
|
|
|
try:
|
|
|
|
|
# Initialize
|
|
|
|
|
evalgamepad.init_gamearea()
|
|
|
|
|
ball = evalgamepad.init_object(evalgamepad.GAMEAREA_MAX_X/2, evalgamepad.GAMEAREA_MAX_Y/2, 15, 15, 8.0, 2.5)
|
|
|
|
|
player1 = evalgamepad.init_player(sys.argv[1], 10, evalgamepad.GAMEAREA_MAX_Y/2-50)
|
|
|
|
|
player2 = evalgamepad.init_player(sys.argv[2], evalgamepad.GAMEAREA_MAX_X-20, evalgamepad.GAMEAREA_MAX_Y/2-50)
|
|
|
|
|
ball = evalgamepad.init_object(evalgamepad.GAMEAREA_MAX_X/2, evalgamepad.GAMEAREA_MAX_Y/2, 20, 20, 8.0, 2.5)
|
|
|
|
|
player1 = evalgamepad.init_player(sys.argv[1], 10, evalgamepad.GAMEAREA_MAX_Y/2-50, 20, 160)
|
|
|
|
|
player2 = evalgamepad.init_player(sys.argv[2], evalgamepad.GAMEAREA_MAX_X-40, evalgamepad.GAMEAREA_MAX_Y/2-50, 20, 160)
|
|
|
|
|
|
|
|
|
|
except IOError as e:
|
|
|
|
|
import errno
|
|
|
|
|