# **************************************************************************** # # # # ::: :::::::: # # Game.py :+: :+: :+: # # +:+ +:+ +:+ # # By: edbernar 0): if(min_time == -1): min_time = time else: min_time = (min(min_time, time)) return(min_time) def getTimeUntilColision(self, limitNeg, limitPos, position, velocity): if(not velocity): return(-1) limit = Game.limits[limitNeg] if velocity < 0 else Game.limits[limitPos] wallDistance = max(limit, position) - min(limit, position) colision_time = wallDistance / abs(velocity) return(colision_time) def getSleepTime(self): time_x = self.getTimeUntilColision("left","right", self.ballPos["pos"][0], self.ballVel[0]) time_z = self.getTimeUntilColision("back","front", self.ballPos["pos"][1], self.ballVel[1]) time_objects = self.check_collision_obstacles() if(time_objects != -1): time_x = min(time_x, time_objects) if(time_x == -1): return(time_z) if(time_z == -1): return(time_x) return(min(time_x, time_z)) def getPlayerDistance(self, player, ballPos): playerPos = player["pos"] return(playerPos - ballPos[0]) def checkGameEndGoal(self): if(self.score[0] < Game.maxScore and self.score[1] < Game.maxScore): return(False) print("someone won the game") winner = 1 if self.score[0] == Game.maxScore else 2 print("player", winner,"won the game") self.endGame(winner) return(True) async def scoreGoal(self, player): self.lastWin = player print("a player suffured from a major skill issue") self.score[player-1] += 1 print("new score :", self.score) self.p1.sync_send({"type":"game","content":{"action":6, "is_opponent": player == 2}}) self.p2.sync_send({"type":"game","content":{"action":6, "is_opponent": player == 1}}) await asyncio.sleep(4.5) if(self.checkGameEndGoal()): return self.prepareGame(True) await asyncio.sleep(3) self.prepareGame() return; def twoPointsDistance(self, pos1, pos2): return(math.sqrt(((pos2[0] - pos1[0]) ** 2) + ((pos2[1] - pos1[1]) ** 2))) def checkJumpersDistance(self, ballPos): for i in range(0, len(self.obstacles)): if(self.obstacles[i]["type"] != 1): continue; if(self.obstacles[i]["isUp"] != self.ballPos["up"]): continue if(self.twoPointsDistance((self.obstacles[i]["pos"]["x"], self.obstacles[i]["pos"]["z"]), ballPos) < Game.jumperRadius): self.p1.sync_send({"type":"game", "content":{"action":8,"name":self.obstacles[i]["name"]}}) self.p2.sync_send({"type":"game", "content":{"action":8,"name":self.obstacles[i]["name"]}}) self.ballPos["up"] = not self.ballPos["up"] def checkWallsColision(self, ballPos): for i in range(0, len(self.obstacles)): if(self.obstacles[i]["type"] != 2): continue; if(self.obstacles[i]["isUp"] != self.ballPos["up"]): continue; if(abs(ballPos[1]) < (Game.wallWidth / 2) + Game.ballRadius): if(abs(self.obstacles[i]["pos"]["x"] - ballPos[0]) < (Game.wallLength / 2) + Game.ballRadius): print("not in wall 2") return(True) return(False) def increaseSpeed(self): x = self.ballVel[0] + (Game.bounceSpeedIncrease * (self.ballVel[0] / self.speed)) y = self.ballVel[1] + (Game.bounceSpeedIncrease * (self.ballVel[1] / self.speed)) self.ballVel = (x, y) self.speed += Game.bounceSpeedIncrease async def updateBall(self): print("AAAAAAAAAAAAAAAAAAAAAAA update") now = time.time() delta = now - self.lastUpdate print("delta :", delta) print("\033[31msleep time diff :", (delta - self.expSleepTime) * 1000, "ms") currentBallPos = self.ballPos["pos"] velX = self.ballVel[0] velZ = self.ballVel[1] newBallPos = (round(currentBallPos[0] + (delta * velX), 5), round(currentBallPos[1] + (delta * velZ), 5)) if(newBallPos[1] <= Game.limits["back"] or newBallPos[1] >= Game.limits["front"]): player = self.p2Pos if newBallPos[1] < 0 else self.p1Pos playerDistance = self.getPlayerDistance(player, newBallPos) if(playerDistance >= -(Game.playerLength / 2) and playerDistance <= Game.playerLength / 2 and player["up"] == self.ballPos["up"]): velX = -((self.speed * 0.80) * (playerDistance / (Game.playerLength / 2))) velZ = self.speed - abs(velX) if(newBallPos[1] > 0): velZ = -velZ self.p1.sync_send({"type":"game","content":{"action":4, "is_opponent": newBallPos[1] < 0}}) self.p2.sync_send({"type":"game","content":{"action":4, "is_opponent": newBallPos[1] > 0}}) else: await self.scoreGoal(1 if newBallPos[1] < 0 else 2) return; elif(newBallPos[0] <= Game.limits["left"] or newBallPos[0] >= Game.limits["right"]): velX = -velX elif(self.checkWallsColision(newBallPos)): velZ = -velZ self.checkJumpersDistance(newBallPos) self.ballVel = (velX, velZ) self.increaseSpeed() self.lastUpdate = now self.ballPos["pos"] = newBallPos self.sendNewBallInfo() def prepareGame(self, stop = False): self.speed = Game.startSpeed self.ballPos = {"pos":(0, 0), "up": False} if(stop): self.ballVel = (0, 0) else: velX = self.speed * (random.randint(-50, 50) / 100) velZ = self.speed - abs(velX) if(self.lastWin == 2): velZ = -velZ self.ballVel = (velX, velZ) self.sendNewBallInfo() self.lastUpdate = time.time() async def gameLoop(self): self.started = True self.sendPlayers({"action":2}) self.prepareGame(True) await asyncio.sleep(3) self.prepareGame() while(not self.end): await self.updateBall() if(self.end): break; sleep_time = self.getSleepTime() print("sleep time : " , sleep_time) self.expSleepTime = sleep_time await asyncio.sleep(sleep_time) print("game end") await self.saveResults() self.p1.game = None self.p2.game = None @sync_to_async def saveResults(self): try: if(self.winner == None): print("unkown winner, setting to 1") self.winner = 1 print("saving results") p1DbUser = User.objects.get(id=self.p1.id) p2DbUser = User.objects.get(id=self.p2.id) results = GameResults.objects.create( player1 = p1DbUser, player2 = p2DbUser, p1Score = self.score[0], p2Score = self.score[1], winner = p1DbUser if self.winner == 1 else p2DbUser, forfeit = self.left != None ) results.save() print("results saved") except Exception as e: self.p1.sendError("Couldn't save last game results", 9104, e) self.p2.sendError("Couldn't save last game results", 9104, e)