人工智能与游戏物理

0 投票
1 回答
59 浏览
提问于 2025-04-12 13:38

我在运行测试的时候,一切都正常,只需要更新一次就可以了。但是,当我让我的AI来输入时,立方体就掉出屏幕了,玩家的位置快速增加,而速度和玩家的y坐标却在快速减少。我现在很困惑,因为我觉得这不是因为和地面碰撞导致的,因为测试运行得很好。也许是AI输入得太快了?这是我项目的GitHub链接 physics-ai-game

  • 我当前的游戏文件:
import pygame
from math import dist

pygame.init()
w, h = 1250, 720

class Direction:
    @staticmethod
    def update(left=0, right=0, jump=0):
        return left, right, jump

class Player:
    def __init__(self, x, y):
        self.rect = pygame.Rect(x, y, 10, 10)
        self.vel_x = 0
        self.vel_y = 0
        self.gravity = 0.2
        self.ground = False
        self.collision_tol = 5

    def update_velo(self, left, right, jump):
        self.vel_x = 300 if right == 1 else 0 if left == 1 else 0
        self.vel_y += self.gravity
        self.vel_y = -10 if jump == 1 else self.vel_y
        print("Velocity X:", self.vel_x)
        print("Velocity Y:", self.vel_y)

    def move(self):
        self.rect.x += self.vel_x
        self.rect.y += self.vel_y
        print("Player Position:", self.rect.x, self.rect.y)

    def collisions(self, objects, walls):

        for object in objects:
            if self.rect.colliderect(object):
                print("Collision detected with object:", object)
                if abs(self.rect.right - object.left) <= self.collision_tol:
                    self.rect.right = object.left
                    self.ground = True
                elif abs(self.rect.left - object.right) <= self.collision_tol:
                    self.rect.left = object.right
                    self.ground = True
                elif self.rect.bottom >= object.top:
                    self.rect.bottom = object.top
                    self.ground = True
                    self.vel_y = 0
                elif self.rect.top <= object.bottom:
                    self.rect.top = object.bottom
                    self.ground = False
                else:
                    self.ground = False
        
        for wall in walls:
            if self.rect.colliderect(wall):
                print("Collision detected with wall:", wall)
                if self.vel_x > 0:
                    self.rect.right = wall.left
                elif self.vel_x < 0:
                    self.rect.left = wall.right

                if self.vel_y > 0:
                    self.rect.bottom = wall.top
                    self.vel_y = 0
                    self.ground = True
                    
                elif self.vel_y < 0:
                    self.rect.top = wall.bottom
                    self.vel_y = 0

    def update(self, left, right, jump, objects, walls):
        self.update_velo(left, right, jump)
        self.move()
        self.collisions(objects, walls)
        print("Player position:", self.rect.x, self.rect.y)

class Game:
    def __init__(self):
        self.display = pygame.display.set_mode((w, h))
        pygame.display.set_caption("AI Game")
        self.clock = pygame.time.Clock()
        self.endpt = pygame.Rect(1200, h - 250, 20, 20)
        self.floor = pygame.Rect(0, h - 20, w, 200)
        self.left_wall = pygame.Rect(0, 0, 20, h)
        self.right_wall = pygame.Rect(w - 20, 0, 20, h)
        self.objects_for_lvl = [
            pygame.Rect(100, h - 100, 100, 80),
            pygame.Rect(250, h - 140, 100, 25),
            pygame.Rect(400, h - 170, 100, 25),
            pygame.Rect(535, h - 170, 75, 25),
            pygame.Rect(735, h - 170, 75, 25),
            pygame.Rect(900, h - 200, 150, 25),
            pygame.Rect(1150, h - 230, 200, 25)
        ]

        self.player = Player(30, 600)
        self.running = True
        self.reset()

    def reset(self):
        self.score = 0
        self.frame_iteration = 0

    def step(self, action):
        self.frame_iteration += 1

        for ev in pygame.event.get():
            if ev.type == pygame.QUIT:
                pygame.quit()
                quit()

        left, right, jump = action
        self.player.update(left, right, jump, self.objects_for_lvl, [self.floor, self.left_wall, self.right_wall])

        reward, game_over = self.calculate_score()

        self._update()

        return reward, game_over, self.score

    def calculate_score(self):
        reward = 0
        game_over = False

        if self.player.rect.colliderect(self.endpt):
            reward += 10
        elif self.player.rect.colliderect(self.floor):
            reward -= 5

        self.score += reward
        game_over = self.player.rect.colliderect(self.left_wall) or self.player.rect.colliderect(self.right_wall)

        return reward, game_over

    def _update(self):    
        self.display.fill('white')  

        for obj in self.objects_for_lvl:  
            pygame.draw.rect(self.display, (128, 128, 128), obj)

        pygame.draw.rect(self.display, (128, 128, 128), self.floor)  
        pygame.draw.rect(self.display, (128, 128, 128), self.left_wall)
        pygame.draw.rect(self.display, (128, 128, 128), self.right_wall)
    
        pygame.draw.rect(self.display, (255, 0, 0), self.player.rect)  # Draw player object
        pygame.draw.rect(self.display, (0, 255, 0), self.endpt)  

        pygame.display.update()


if __name__ == "__main__":
    game = Game()
    while game.running:
        action = Direction.update(1, 0, 0) # move left once 
        print("Action:", action)
        reward, game_over, score = game.step(action)
        if game_over:
            print("Game Over")
            game.running = False

1 个回答

暂无回答

撰写回答