如何让我的 Sprite 向鼠标位置发射一个对象? [英] How can I make my Sprite launch an object towards the mouse position?

查看:45
本文介绍了如何让我的 Sprite 向鼠标位置发射一个对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于学校项目,我需要通过实现向鼠标位置射击 Kunais/Shurikens 的方式来完成下面的 pygame 程序,以便能够击中敌人的精灵.

导入pygame导入数学随机导入从 pygame.locals 导入 *pygame.init()fenetre = pygame.display.set_mode((640,480), RESIZABLE)暂停 = 假类人():def __init__(self,image,x=0,y=0,directionX=1,directionY=1):self.image = pygame.image.load(image).convert_alpha()自我.x = x自我.y = yself.directionX = 方向Xself.directionY = 方向Y定义移动(自我):如果 self.x==0:self.directionX=1如果 self.x==640-60:self.directionX=-1如果 self.y==0:self.directionY=1如果 self.y==480-100:self.directionY=-1self.x+=self.directionXself.y+=self.directionY喜欢 = pygame.image.load("background.png").convert_alpha()火影忍者 = perso("火影忍者.png")tobi = perso("tobi.png", 250, 100)苦无 = perso("苦无.png")苦无.x = 火影忍者.x + 40苦无.y = 火影忍者.y + 70继续者 = 真pygame.key.set_repeat(100, 25)myfont = pygame.font.SysFont("monospace", 40)颜色红色 = (255, 0, 0)颜色黑色 = (0, 0, 0)颜色白色 = (255, 255, 255)颜色蓝色 = (0, 0, 255)火影忍者 = 10比托比 = 3结果 = 0而继续者:如果 int(naruto.x) >= int(tobi.x) 并且 int(naruto.x) <int(tobi.x + 60) and int(naruto.y) >= int(tobi.y) and int(naruto.y) <整数(tobi.y + 105):火影忍者 -= 1火影忍者.x = 0火影忍者.y = 0如果 int(naruto.x + 50) >= int(tobi.x) 并且 int(naruto.x + 50) = int(tobi.y) and int(naruto.y) <整数(tobi.y + 105):火影忍者 -= 1火影忍者.x = 0火影忍者.y = 0如果 int(naruto.x) >= int(tobi.x) 并且 int(naruto.x) <int(tobi.x + 60) and int(naruto.y + 105) >= int(tobi.y) and int(naruto.y + 105) <整数(tobi.y + 105):火影忍者 -= 1火影忍者.x = 0火影忍者.y = 0如果 int(naruto.x + 50) >= int(tobi.x) 并且 int(naruto.x + 50) = int(tobi.y) and int(naruto.y + 105) <整数(tobi.y + 105):火影忍者 -= 1火影忍者.x = 0火影忍者.y = 0如果 vieNaruto <= 0:结果 = 1继续者 = 假如果 vieTobi == 0:结果 = 2继续者 = 假textVieNaruto = myfont.render("Vie Naruto : "+str(vieNaruto), True, colorRed)textVieTobi = myfont.render("Vie Tobi : "+ str(vieTobi), True, colorRed)对于 pygame.event.get() 中的事件:"""GESTION DU CLAVIER"""如果 event.type == 退出:继续者 = 假elif event.type == KEYDOWN:如果 event.key == K_SPACE:暂停 = 真而暂停 == 真:对于 pygame.event.get() 中的事件:如果 event.type == KEYDOWN:如果 event.key==K_SPACE:暂停 = 假如果 event.key == K_UP 并且 5 <= naruto.y:火影忍者.y -= 5如果 event.key == K_DOWN 和 naruto.y <= 375:火影忍者.y += 5如果 event.key == K_LEFT 并且 5 <= naruto.x :火影忍者.x -= 5如果 event.key == K_RIGHT 和 naruto.x <= 575:火影忍者.x += 5tobi.move()tobi.move()fenetre.blit(喜欢,(0,0))fenetre.blit(textVieNaruto, (400,0))fenetre.blit(textVieTobi, (400,30))fenetre.blit(火影忍者.image,(火影忍者.x,火影忍者.y))fenetre.blit(tobi.image,(tobi.x,tobi.y))pygame.time.Clock().tick(30)pygame.display.update()如果结果 == 1:而真:喜欢 = pygame.image.load("Defeat.png").convert_alpha()fenetre.blit(喜欢,(0,0))pygame.display.update()如果结果 == 2:而真:喜欢 = pygame.image.load("Victory.png").convert_alpha()fenetre.blit(喜欢,(0,0))pygame.display.update()

额外的 png 文件可见于:

我们的游戏会有不同的场景(标题场景、游戏场景、游戏结束场景),所以现在让我们实现它们:

导入pygame导入 pygame.freetypepygame.init()FONT = pygame.freetype.SysFont(None, 32)类 SimpleScene:def __init__(self, text, background, next_scene):如果背景:self.background = pygame.image.load(background).convert()别的:self.background = pygame.Surface((640, 480))self.background.fill(pygame.Color('white'))如果文本:FONT.render_to(self.background, (100, 200), text, pygame.Color('black'))FONT.render_to(self.background, ( 99, 199), text, pygame.Color('red'))self.next_scene = next_scene定义开始(自我):经过def draw(self, screen):screen.blit(self.background, (0, 0))定义更新(自我,事件,dt):对于事件中的事件:如果 event.type == pygame.KEYDOWN:如果 event.key == pygame.K_SPACE:返回 self.next_scene课堂游戏:def __init__(self):self.background = pygame.image.load('background.png').convert()定义开始(自我):经过def draw(self, screen):screen.blit(self.background, (0, 0))定义更新(自我,事件,dt):对于事件中的事件:如果 event.type == pygame.KEYDOWN:如果 event.key == pygame.K_SPACE:返回胜利"定义主():屏幕 = pygame.display.set_mode((640, 480))时钟 = pygame.time.Clock()场景 = {'TITLE': SimpleScene('PRESS SPACE TO START', 'background.png', 'GAME'),'游戏':游戏(),'胜利':SimpleScene('你赢了!',无,'TITLE'),'DEFEAT': SimpleScene('你输了!', None, 'TITLE'),}场景 = 场景 ['TITLE']dt = 0为真:事件 = pygame.event.get()对于事件中的 e:如果 e.type == pygame.QUIT:返回next_scene = scene.update(events, dt)如果下一个场景:场景=场景[next_scene]场景.开始()场景绘制(屏幕)pygame.display.flip()dt = 时钟.tick(60)如果 __name__ == '__main__':主要的()

这允许我们通过按空格来循环浏览游戏场景.

现在让我们实现核心游戏.首先,我们需要一些精灵,所以让我们创建一个 Actor 类并准备游戏场景以显示和重置我们的精灵.我们使用一些 pygame 的基本内容,例如

是时候采取一些行动了.让我们在我们的演员中实现一些行为.我们创建了我们想要的每种不同行为的功能.一个让托比在屏幕上移动,一个让鸣人通过键盘控制,一个让苦无.

由于我们使用 Vector 类来表示精灵的位置和方向,因此只需进行减法即可使 kunai 向鼠标位置移动.

完整代码如下:

导入pygame导入 pygame.freetypepygame.init()FONT = pygame.freetype.SysFont(None, 32)类 SimpleScene:def __init__(self, text, background, next_scene):如果背景:self.background = pygame.image.load(background).convert()别的:self.background = pygame.Surface((640, 480))self.background.fill(pygame.Color('white'))如果文本:FONT.render_to(self.background, (100, 200), text, pygame.Color('black'))FONT.render_to(self.background, ( 99, 199), text, pygame.Color('red'))self.next_scene = next_scene定义开始(自我):经过def draw(self, screen):screen.blit(self.background, (0, 0))定义更新(自我,事件,dt):对于事件中的事件:如果 event.type == pygame.KEYDOWN:如果 event.key == pygame.K_SPACE:返回 self.next_scenedef tobi_ai(self, dt):self._update_pos(dt)# 碰到屏幕边缘时改变方向display = pygame.display.get_surface().get_rect()如果 self.rect.bottom >display.bottom 或 self.rect.top <0: self.direction.y *= -1如果 self.rect.right >display.right 或 self.rect.left <0: self.direction.x *= -1self._keep_on_screen()def player_ai(self, dt):# 如果箭头键被按下,改变方向self.direction = pygame.Vector2()按下 = pygame.key.get_pressed()如果按下[pygame.K_UP] 或按下[pygame.K_w]: self.direction += (0, -1)如果按下[pygame.K_DOWN] 或按下[pygame.K_s]: self.direction += (0, 1)如果按下[pygame.K_LEFT] 或按下[pygame.K_a]: self.direction += (-1, 0)如果按下[pygame.K_RIGHT]或按下[pygame.K_d]:self.direction += (1, 0)self._update_pos(dt)self._keep_on_screen()def kunai_ai(self, dt):self._update_pos(dt)display = pygame.display.get_surface().get_rect()# 飞到屏幕外就死如果不是 display.contains(self.rect):self.kill()类演员(pygame.sprite.Sprite):def __init__(self, image, pos, direction=(0, 0), speed=20, behavior=None,rotate=False):super().__init__()self.image = 图像self.rect = self.image.get_rect(center=pos)# 使用向量表示位置和方向可以轻松计算移动和旋转self.pos = pygame.Vector2(*pos)self.direction = pygame.Vector2(*direction)如果旋转:self.image = pygame.transform.rotate(self.image, self.direction.angle_to(pygame.Vector2(1,0)))self.speed = 速度自我.行为 = 行为定义更新(自我,DT):如果自我行为:self.behaviour(self, dt)def _update_pos(self, dt):如果 self.direction.length() >0:self.pos = self.pos + (self.direction.normalize() * self.speed * dt/100)self.rect.center = int(self.pos.x), int(self.pos.y)def _keep_on_screen(self):self.rect.center = self.posdisplay = pygame.display.get_surface().get_rect()self.rect.clamp_ip(显示)self.pos.x, self.pos.y = self.rect.center课堂游戏:def __init__(self):self.background = pygame.image.load('background.png').convert()self.images = {'tobi': pygame.image.load('tobi.png').convert_alpha(),'火影忍者':pygame.image.load('火影忍者.png').convert_alpha(),'苦无':pygame.image.load('苦无.png').convert_alpha()}self.sprites = pygame.sprite.Group()self.kunais = pygame.sprite.Group()定义开始(自我):self.sprites.empty()self.kunais.empty()self.naruto = Actor(self.images['naruto'], (50, 150), behavior=player_ai)self.tobi = Actor(self.images['tobi'], (450, 300), (1, 1), behavior=tobi_ai)self.sprites.add(self.火影忍者)self.sprites.add(self.tobi)self.player_lives = 10self.enemy_lives = 3def draw(self, screen):screen.blit(self.background, (0, 0))self.sprites.draw(屏幕)FONT.render_to(screen, (430, 10), '火影忍者:' , pygame.Color('red'))FONT.render_to(screen, (550, 10), str(self.player_lives), pygame.Color('red'))FONT.render_to(screen, (430, 50), 'Tobi:', pygame.Color('red'))FONT.render_to(screen, (550, 50), str(self.enemy_lives), pygame.Color('red'))定义更新(自我,事件,dt):对于事件中的事件:如果 event.type == pygame.MOUSEBUTTONDOWN:苦无=演员(self.images['苦无'],self.naruto.pos,event.pos-self.naruto.pos,速度=35,行为=苦无爱,旋转=真)self.sprites.add(苦无)self.kunais.add(kunai)self.sprites.update(dt)#苦无击中托比# 我们使用 https://www.pygame.org/docs/ref/sprite.html#pygame.sprite.spritecollide# 碰撞检测对于 pygame.sprite.spritecollide(self.tobi, self.kunais, True) 中的精灵:self.enemy_lives -= 1如果 self.enemy_lives <= 0:返回胜利"# tobi 击中火影忍者如果 self.tobi.rect.colliderect(self.naruto.rect):self.player_lives -= 1如果 self.player_lives <= 0:返回失败"self.naruto.pos = pygame.Vector2(50, 150)self.tobi.pos.x = max(self.tobi.pos.x, 400)定义主():屏幕 = pygame.display.set_mode((640, 480))时钟 = pygame.time.Clock()场景 = {'TITLE': SimpleScene('PRESS SPACE TO START', 'background.png', 'GAME'),'游戏':游戏(),'胜利':SimpleScene('你赢了!',无,'TITLE'),'DEFEAT': SimpleScene('你输了!', None, 'TITLE'),}场景 = 场景 ['TITLE']dt = 0为真:事件 = pygame.event.get()对于事件中的 e:如果 e.type == pygame.QUIT:返回next_scene = scene.update(events, dt)如果下一个场景:场景=场景[next_scene]场景.开始()场景绘制(屏幕)pygame.display.flip()dt = 时钟.tick(60)如果 __name__ == '__main__':主要的()

现在我们有一个简单的游戏,可重玩且易于扩展.请随意使用此代码.

For a school project, I need to finish up the pygame program below by implementing a way of shooting Kunais/Shurikens towards the mouse position, to be able to hit the enemy sprite.

import pygame
import math
import random
from pygame.locals import * 


pygame.init()
fenetre = pygame.display.set_mode((640,480), RESIZABLE) 
pause = False

class perso():
  def __init__(self,image,x=0,y=0,directionX=1,directionY=1):
    self.image = pygame.image.load(image).convert_alpha()
    self.x = x
    self.y = y
    self.directionX = directionX
    self.directionY = directionY

  def move(self):
      if self.x==0:
        self.directionX=1
      if self.x==640-60:
        self.directionX=-1
      if self.y==0:
        self.directionY=1
      if self.y==480-100:
        self.directionY=-1
      self.x+=self.directionX
      self.y+=self.directionY


fond = pygame.image.load("background.png").convert_alpha() 

naruto = perso("naruto.png")
tobi = perso("tobi.png", 250, 100)
kunai = perso("kunai.png")

kunai.x = naruto.x + 40
kunai.y = naruto.y + 70

continuer = True

pygame.key.set_repeat(100, 25)

myfont = pygame.font.SysFont("monospace", 40)
colorRed = (255, 0, 0)
colorBlack = (0, 0, 0)
colorWhite = (255, 255, 255)
colorBlue = (0, 0, 255)

vieNaruto = 10
vieTobi = 3
result = 0


while continuer:

  if int(naruto.x) >= int(tobi.x) and int(naruto.x) < int(tobi.x + 60) and int(naruto.y) >= int(tobi.y) and int(naruto.y) < int(tobi.y + 105):
    vieNaruto -= 1
    naruto.x = 0
    naruto.y = 0

  if int(naruto.x + 50) >= int(tobi.x) and int(naruto.x + 50) < int(tobi.x + 60) and int(naruto.y) >= int(tobi.y) and int(naruto.y) < int(tobi.y + 105):
    vieNaruto -= 1
    naruto.x = 0
    naruto.y = 0

  if int(naruto.x) >= int(tobi.x) and int(naruto.x) < int(tobi.x + 60) and int(naruto.y + 105) >= int(tobi.y) and int(naruto.y + 105) < int(tobi.y + 105):
    vieNaruto -= 1
    naruto.x = 0
    naruto.y = 0

  if int(naruto.x + 50) >= int(tobi.x) and int(naruto.x + 50) < int(tobi.x + 60) and int(naruto.y + 105) >= int(tobi.y) and int(naruto.y + 105) < int(tobi.y + 105):
    vieNaruto -= 1
    naruto.x = 0
    naruto.y = 0

  if vieNaruto <= 0:
    result = 1
    continuer = False

  if vieTobi == 0:
    result = 2
    continuer = False

  textVieNaruto = myfont.render("Vie Naruto : "+str(vieNaruto), True, colorRed)

  textVieTobi = myfont.render("Vie Tobi : "+ str(vieTobi), True, colorRed)

  for event in pygame.event.get():

    """GESTION DU CLAVIER"""

    if event.type == QUIT:
      continuer = False 
    elif event.type == KEYDOWN:
      if event.key == K_SPACE:
        pause = True
        while pause == True:
          for event in pygame.event.get():
            if event.type == KEYDOWN:
                if event.key==K_SPACE:
                    pause = False
      if event.key == K_UP and 5 <= naruto.y:
        naruto.y -= 5
      if event.key == K_DOWN and naruto.y <= 375:
        naruto.y += 5
      if event.key == K_LEFT and 5 <= naruto.x :
        naruto.x -= 5
      if event.key == K_RIGHT and naruto.x <= 575:
        naruto.x += 5



  tobi.move()
  tobi.move() 
  fenetre.blit(fond,(0,0))
  fenetre.blit(textVieNaruto, (400,0))
  fenetre.blit(textVieTobi, (400,30))
  fenetre.blit(naruto.image,(naruto.x,naruto.y))
  fenetre.blit(tobi.image,(tobi.x,tobi.y))

  pygame.time.Clock().tick(30)  
  pygame.display.update() 


if result == 1:
  while True :
    fond = pygame.image.load("Defeat.png").convert_alpha()
    fenetre.blit(fond,(0,0))
    pygame.display.update()

if result == 2:
  while True :
    fond = pygame.image.load("Victory.png").convert_alpha()
    fenetre.blit(fond,(0,0))
    pygame.display.update()

The extra png files are visible on : https://repl.it/@LeVeveysan/ISNNaruto

Can anyone help me out on this ? I know how to get the mouse position but I can't get a class to work properly.

Sincirely

解决方案

Let's discard everything and start from scratch and make use of pygame features like sprites and vector math.

We begin with a basic skeleton of a pygame game, a simple window:

import pygame

def main():
    screen = pygame.display.set_mode((640, 480))
    clock = pygame.time.Clock()
    while True:
        events = pygame.event.get()
        for e in events:
            if e.type == pygame.QUIT:
                return
        screen.fill(pygame.Color('grey'))
        pygame.display.flip()
        clock.tick(60)

if __name__ == '__main__':
    main()

Our game will have different scenes (title scene, game scene, game-over scene), so let's implement them now:

import pygame
import pygame.freetype 

pygame.init()
FONT = pygame.freetype.SysFont(None, 32)

class SimpleScene:
    def __init__(self, text, background, next_scene):
        if background:
            self.background = pygame.image.load(background).convert()
        else:
            self.background = pygame.Surface((640, 480))
            self.background.fill(pygame.Color('white'))

        if text:
            FONT.render_to(self.background, (100, 200), text, pygame.Color('black'))
            FONT.render_to(self.background, ( 99, 199), text, pygame.Color('red'))

        self.next_scene = next_scene

    def start(self):
        pass

    def draw(self, screen):
        screen.blit(self.background, (0, 0))

    def update(self, events, dt):
        for event in events:
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_SPACE:
                    return self.next_scene

class Game:
    def __init__(self):
        self.background = pygame.image.load('background.png').convert()

    def start(self):
        pass

    def draw(self, screen):
        screen.blit(self.background, (0, 0))

    def update(self, events, dt):
        for event in events:
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_SPACE:
                    return 'VICTORY'

def main():
    screen = pygame.display.set_mode((640, 480))
    clock = pygame.time.Clock()
    scenes = {
        'TITLE': SimpleScene('PRESS SPACE TO START', 'background.png', 'GAME'),
        'GAME': Game(),
        'VICTORY': SimpleScene('YOU WIN!', None, 'TITLE'),
        'DEFEAT': SimpleScene('YOU LOSE!', None, 'TITLE'),
    }
    scene = scenes['TITLE']
    dt = 0
    while True:
        events = pygame.event.get()
        for e in events:
            if e.type == pygame.QUIT:
                return

        next_scene = scene.update(events, dt)
        if next_scene:
            scene = scenes[next_scene]
            scene.start()

        scene.draw(screen)
        pygame.display.flip()
        dt = clock.tick(60)

if __name__ == '__main__':
    main()

This allows us to cycle through the game scenes by pressing space.

Now let's implement the core game. First, we need some sprites, so let's create an Actor class and prepare the game scene to display and reset our sprites. We use some of pygame's basic stuff, like the Sprite class.

...
class Actor(pygame.sprite.Sprite):
    def __init__(self, image, pos, direction):
       super().__init__()
       self.image = image
       self.rect = self.image.get_rect(center=pos)
       self.pos = pygame.Vector2(*pos)
       self.direction = pygame.Vector2(*direction)

class Game:
    def __init__(self):
        self.background = pygame.image.load('background.png').convert()
        self.images = {
            'tobi': pygame.image.load('tobi.png').convert_alpha(),
            'naruto': pygame.image.load('naruto.png').convert_alpha(),
            'kunai': pygame.image.load('kunai.png').convert_alpha()
        }
        self.sprites = pygame.sprite.Group()

    def start(self):
        self.sprites.empty()
        self.sprites.add(Actor(self.images['naruto'], (50, 150), (0, 0)))
        self.sprites.add(Actor(self.images['tobi'], (450, 300), (0, 0)))

    def draw(self, screen):
        screen.blit(self.background, (0, 0))
        self.sprites.draw(screen)

    def update(self, events, dt):
        for event in events:
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_SPACE:
                    return 'VICTORY'
        self.sprites.update()
...

Time for some action. Let's implement some behaviour in our actors. We create function of each different kind of behaviour we want. One for Tobi to move along the screen, one for Naruto to be controlled by the keyboard, and one for the kunais.

Since we use the Vector class for the position and direction of our sprites, is simply a matter of substraction to make the kunai move towards the mouse position.

Here's the full code:

import pygame
import pygame.freetype 

pygame.init()
FONT = pygame.freetype.SysFont(None, 32)

class SimpleScene:
    def __init__(self, text, background, next_scene):
        if background:
            self.background = pygame.image.load(background).convert()
        else:
            self.background = pygame.Surface((640, 480))
            self.background.fill(pygame.Color('white'))

        if text:
            FONT.render_to(self.background, (100, 200), text, pygame.Color('black'))
            FONT.render_to(self.background, ( 99, 199), text, pygame.Color('red'))

        self.next_scene = next_scene

    def start(self):
        pass

    def draw(self, screen):
        screen.blit(self.background, (0, 0))

    def update(self, events, dt):
        for event in events:
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_SPACE:
                    return self.next_scene

def tobi_ai(self, dt):
    self._update_pos(dt)

    # change direction when hitting the edge of the screen
    display = pygame.display.get_surface().get_rect()
    if self.rect.bottom > display.bottom or self.rect.top < 0: self.direction.y *= -1
    if self.rect.right > display.right or self.rect.left < 0: self.direction.x *= -1

    self._keep_on_screen()

def player_ai(self, dt):

    # alter direction if arrow keys are pressed
    self.direction = pygame.Vector2()
    pressed = pygame.key.get_pressed()
    if pressed[pygame.K_UP] or pressed[pygame.K_w]: self.direction += (0, -1)
    if pressed[pygame.K_DOWN] or pressed[pygame.K_s]: self.direction += (0, 1)
    if pressed[pygame.K_LEFT] or pressed[pygame.K_a]: self.direction += (-1, 0)
    if pressed[pygame.K_RIGHT] or pressed[pygame.K_d]: self.direction += (1, 0)

    self._update_pos(dt)
    self._keep_on_screen()

def kunai_ai(self, dt):
    self._update_pos(dt)
    display = pygame.display.get_surface().get_rect()

    # just fly around and die if out of screen
    if not display.contains(self.rect):
        self.kill()

class Actor(pygame.sprite.Sprite):
    def __init__(self, image, pos, direction=(0, 0), speed=20, behaviour=None, rotate=False):
       super().__init__()
       self.image = image
       self.rect = self.image.get_rect(center=pos)
       # using vectors for position and direction makes it easy to calculate movement and rotation
       self.pos = pygame.Vector2(*pos)
       self.direction = pygame.Vector2(*direction)
       if rotate:
           self.image = pygame.transform.rotate(self.image, self.direction.angle_to(pygame.Vector2(1,0)))
       self.speed = speed
       self.behaviour = behaviour

    def update(self, dt):
        if self.behaviour:
            self.behaviour(self, dt)

    def _update_pos(self, dt):
        if self.direction.length() > 0:
            self.pos = self.pos + (self.direction.normalize() * self.speed * dt/100)
            self.rect.center = int(self.pos.x), int(self.pos.y)

    def _keep_on_screen(self):
        self.rect.center = self.pos
        display = pygame.display.get_surface().get_rect()
        self.rect.clamp_ip(display)
        self.pos.x, self.pos.y = self.rect.center

class Game:
    def __init__(self):
        self.background = pygame.image.load('background.png').convert()
        self.images = {
            'tobi': pygame.image.load('tobi.png').convert_alpha(),
            'naruto': pygame.image.load('naruto.png').convert_alpha(),
            'kunai': pygame.image.load('kunai.png').convert_alpha()
        }
        self.sprites = pygame.sprite.Group()
        self.kunais = pygame.sprite.Group()

    def start(self):
        self.sprites.empty()
        self.kunais.empty()
        self.naruto = Actor(self.images['naruto'], (50, 150), behaviour=player_ai)
        self.tobi = Actor(self.images['tobi'], (450, 300), (1, 1), behaviour=tobi_ai)
        self.sprites.add(self.naruto)
        self.sprites.add(self.tobi)
        self.player_lives = 10
        self.enemy_lives = 3

    def draw(self, screen):
        screen.blit(self.background, (0, 0))
        self.sprites.draw(screen)
        FONT.render_to(screen, (430, 10), 'Naruto:' , pygame.Color('red'))
        FONT.render_to(screen, (550, 10), str(self.player_lives), pygame.Color('red'))
        FONT.render_to(screen, (430, 50), 'Tobi:', pygame.Color('red'))
        FONT.render_to(screen, (550, 50), str(self.enemy_lives), pygame.Color('red'))

    def update(self, events, dt):
        for event in events:
            if event.type == pygame.MOUSEBUTTONDOWN:
                kunai = Actor(self.images['kunai'], 
                               self.naruto.pos, 
                               event.pos-self.naruto.pos, 
                               speed=35, 
                               behaviour=kunai_ai,
                               rotate=True)
                self.sprites.add(kunai)
                self.kunais.add(kunai)

        self.sprites.update(dt)

        # kunai hits tobi
        # we use https://www.pygame.org/docs/ref/sprite.html#pygame.sprite.spritecollide 
        # for collition detection
        for sprite in pygame.sprite.spritecollide(self.tobi, self.kunais, True):
            self.enemy_lives -= 1
            if self.enemy_lives <= 0:
                return 'VICTORY'

        # tobi hits naruto
        if self.tobi.rect.colliderect(self.naruto.rect):
            self.player_lives -= 1
            if self.player_lives <= 0:
                return 'DEFEAT'
            self.naruto.pos = pygame.Vector2(50, 150)
            self.tobi.pos.x = max(self.tobi.pos.x, 400)

def main():
    screen = pygame.display.set_mode((640, 480))
    clock = pygame.time.Clock()
    scenes = {
        'TITLE': SimpleScene('PRESS SPACE TO START', 'background.png', 'GAME'),
        'GAME': Game(),
        'VICTORY': SimpleScene('YOU WIN!', None, 'TITLE'),
        'DEFEAT': SimpleScene('YOU LOSE!', None, 'TITLE'),
    }
    scene = scenes['TITLE']
    dt = 0
    while True:
        events = pygame.event.get()
        for e in events:
            if e.type == pygame.QUIT:
                return

        next_scene = scene.update(events, dt)
        if next_scene:
            scene = scenes[next_scene]
            scene.start()

        scene.draw(screen)

        pygame.display.flip()
        dt = clock.tick(60)

if __name__ == '__main__':
    main()

Now we have a simple game that's replayable and easily extendable. Feel free to use this code for whatever you like.

这篇关于如何让我的 Sprite 向鼠标位置发射一个对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆