2012-12-05 65 views
-1

我正在製作一個克隆基於教程的pong的程序,我已經有了它的程序,它是多人與兩個單獨的人。我想在程序中添加一個AI,而不是播放器2.我一直堅持這一段時間,並希望得到任何幫助!這是當前的代碼:蟒蛇克隆的蟒蛇和pygame的人工智能

import sys, os, math, random, pygame from pygame.locals import *

class paddle(pygame.sprite.Sprite):

def __init__(self, xy): 
    pygame.sprite.Sprite.__init__(self) 
    self.image = pygame.image.load(os.path.join('assets', 'pong_paddle.gif')) 
    self.rect = self.image.get_rect() 

    self.rect.centerx, self.rect.centery = xy 

    self.movementspeed = 5 

    self.velocity = 0 

def up(self): 
    # increases vertical velocity 
    self.velocity -= self.movementspeed 

def down(self): 
    # decreases vertical velocity 
    self.velocity += self.movementspeed 

def move(self, dy): 
    # moves the paddle y, doesn't go out of top or bottom 
    if self.rect.bottom + dy > 400: 
     self.rect.bottom = 400 
    elif self.rect.top + dy < 0: 
     self.rect.top = 0 
    else: 
     self.rect.y += dy 

def update(self): 
    # makes the paddle move every frame 
    self.move(self.velocity) 

class aiplayer(object):

def __init__(self): 
    self.bias = random.random() - 0.5 
    self.hit_count = 0 



def update(self, paddle, game,): 


    if (paddle.rect.centerx < game.bounds.centerx and game.ball.rect.centerx < game.bounds.centerx) or (paddle.rect.centerx > game.bounds.centerx and game.ball.rect.centerx > game.bounds.centerx): 
     delta = (paddle.rect.centery + self.bias * paddle.rect.height) - game.ball.rect.centery 
     if abs(delta) > paddle.velocity: 
      if delta > 0: 
       paddle.direction = -1 
      else: 
       paddle.direction = 1 
     else: 
      paddle.direction = 0 
    else: 
     paddle.direction = 0 

def hit(self): 
    self.hit_count += 1 
    if self.hit_count > 6: 
     self.bias = random.random() - 0.5 
     self.hit_count = 0 

def lost(self): 
    self.bias = random.random() - 0.5 

    def won(self): 
     pass 


def render(self, surface): 

    x, y = self.location 
    w, h = self.image.get_size() 
    surface.blitz(self.image, (x-w/2, y-h/2)) 

class Ball(pygame.sprite.Sprite):

def __init__(self, xy): 
    pygame.sprite.Sprite.__init__(self) 
    self.image = pygame.image.load(os.path.join('assets', 'pong_ball.gif')) 
    self.rect = self.image.get_rect() 

    self.rect.centerx, self.rect.centery = xy 
    self.maxspeed = 10 
    self.servespeed = 5 
    self.velx = 0 
    self.vely = 0 

def reset(self): 
    self.rect.centerx, self.rect.centery = 400, 200 
    self.velx = 0 
    self.vely = 0 

def serve(self): 
    angle = random.randint(-45, 45) 

    if abs(angle) < 5 or abs(angle-180) < 5: 
     angle = random.randint(10, 20) 

    if random.random() > .5: 
     angle += 180 

    # this gets the velocity for the x and y coords 
    x = math.cos(math.radians(angle)) 
    y = math.sin(math.radians(angle)) 

    self.velx = self.servespeed * x 
    self.vely = self.servespeed * y 

class Game(object):

def __init__(self): 

    pygame.init() 

    # creates the window 
    self.window = pygame.display.set_mode((800, 400)) 

    # makes a clock 
    self.clock = pygame.time.Clock() 

    # window title 
    pygame.display.set_caption("Pong") 

    # tells pygame to watch for these certain events so we can close window 
    pygame.event.set_allowed([QUIT, KEYDOWN, KEYUP]) 

    self.background = pygame.Surface((800, 400)) 
    self.background.fill((55, 255, 85)) 
    pygame.draw.line(self.background, (0,0,0), (400, 0), (400, 400), 2) 
    self.window.blit(self.background, (0,0)) 
    #lets the background show up 
    pygame.display.flip() 



    #renders the sprites so that they actually show up 
    self.sprites = pygame.sprite.RenderUpdates() 

    # makes the paddles, adds to sprite group 
    self.leftpaddle = paddle((50, 200)) 
    self.sprites.add(self.leftpaddle) 
    self.rightpaddle = paddle((750, 200)) 
    self.sprites.add(self.rightpaddle) 

    # makes the ball 
    self.ball = Ball((400, 200)) 
    self.sprites.add(self.ball) 


def run(self): 
    # this lets the game run using a loop so its always active and never closes 
    running = True 

    while running: 
     self.clock.tick(60) 

     # pygame event, if user closes the game, then stop running 
     running = self.handleEvents() 

     pygame.display.set_caption("Pong %d fps" % self.clock.get_fps()) 

     self.manageBall() 

     # updates the sprites(paddles, ball) 
     for sprite in self.sprites: 
      sprite.update() 

     # renders the sprites 
     self.sprites.clear(self.window, self.background) 
     dirty = self.sprites.draw(self.window) 
     pygame.display.update(dirty) 

def handleEvents(self): 

    for event in pygame.event.get(): 
     if event.type == QUIT: 
      return False 

     elif event.type == KEYDOWN: 
      if event.key == K_ESCAPE: 
       return False 

      # controls the right paddle 
      if event.key == K_w: 
       self.leftpaddle.up() 
      if event.key == K_s: 
       self.leftpaddle.down() 
      if event.key == K_UP: 
       self.rightpaddle.up() 
      if event.key == K_DOWN: 
       self.rightpaddle.down() 

      # serves the ball 
      if event.key == K_SPACE: 
       if self.ball.velx == 0 and self.ball.vely == 0: 
        self.ball.serve() 

     elif event.type == KEYUP: 
      if event.key == K_w: 
       self.leftpaddle.down() 
      if event.key == K_s: 
       self.leftpaddle.up() 
      if event.key == K_UP: 
       self.rightpaddle.down() 
      if event.key == K_DOWN: 
       self.rightpaddle.up() 

     elif event.type == 


    return True 



def manageBall(self): 

    # this moves the ball 
    self.ball.rect.x += self.ball.velx 
    self.ball.rect.y += self.ball.vely 

    if self.ball.rect.top < 0: 
     self.ball.rect.top = 1 

     # makes the ball bounce 
     self.ball.vely *= -1 

    elif self.ball.rect.bottom > 400: 
     self.ball.rect.bottom = 399 

     # makes ball bounce off bottom 
     self.ball.vely *= -1 

    # resets the ball if it hits the left or right screen 
    if self.ball.rect.left < 0: 
     self.ball.reset() 
     return 

    elif self.ball.rect.right > 800: 
     self.ball.reset() 
     return 

    collision = pygame.sprite.spritecollide(self.ball, [self.leftpaddle, self.rightpaddle], dokill = False) 

    if len(collision) > 0: 
     hitpaddle = collision[0] 

     # sends the ball back 
     self.ball.velx *= -1 

     # makes sure the ball doesn't get stuck in the paddle 
     self.ball.rect.x += self.ball.velx 

# makes the game and runs it if __name__ == '__main__': game = Game() game.run()

+4

你應該提供一個更具體的問題。 –

+0

您是否考慮過每x毫秒調用一次函數,查看球的位置,並將球移向球?您也可以將其註冊爲活動。 –

+1

它是不是真的「AI」你是以後呢?如果槳在球的「下方」,則將球向上移動,如果球在「球」下方則將其向下移動。 –

回答

0

做一個功能AI在aiplayer,並將它或返回上下

int AI(self.position,ball.position): 
     if self.y>ball.y: 
      return -1 
     elif self.y<ball.y: 
      return 1 

然後,在更新()代碼對於aiplayer,請執行類似於此操作的

self.y += movespeed*AI(self.position,ball.position) 

然後,向上或向下移動槳根據球的位置(如果您添加或減去MOVESPEED得到槳走正確的方向,你可能需要切換)。此外,使用槳葉的中心可能會更有效,因此它不會將槳葉的頂部或底部邊緣置於球體上。

+0

我做了你所說的並且在遊戲函數中調用了aiplayer函數,希望它能運行但是在python shell中我得到了錯誤信息'遊戲'對象沒有屬性'aiplayer'。任何想法是什麼意思,我試圖解決它,但似乎無法得到它。 – Foemilod

+0

你把AI函數放在aiplayer類中了嗎?如果你沒有,請確保你這樣做。然後,如果這不能解決它,請調用self.AI()而不是AI() – Chachmu