使用pygame使子弹移动到光标

时间:2015-06-30 21:21:38

标签: python pygame sprite

我正在写一个相对复杂的平台游戏,其中玩家使用wasd移动并使用鼠标进行拍摄。目标是让子弹在单击时移动到鼠标的位置。我有一些代码可以工作,但随着角度从0或90(直线左/右或直线向上/向下)越来越远,子弹最终位置离光标越来越远。我相当肯定问题只是因为x和y的变化是浮点和x,子弹的y位置不能是浮点,所以发生了舍入问题。我已经尝试了许多基于论坛搜索的不同方法,所有这些方法都有同样的问题。我附上了最相关的文件(特别注意子弹 init 类)。任何建议或帮助将不胜感激。为了记录,这只是玩家类而不是主要的。

import pygame
import level
import platform
##import enemies
import math
pygame.init()

## sets up colors that need to be used in every part of the program
black=(0,0,0)
white=(255,255,255)
red=(255,0,0)
green=(0,255,0)
blue=(0,0,255)


class Player(pygame.sprite.Sprite):
    ## This class represents the player. It is inhariting from the Sprite class in Pygame
    window=None
    screen_width=0
    screen_height=0
    width=None
    height=None
    x_velocity=0
    y_velocity=0
    chrono_level=500
    ball_damage=0
    bomb_damage=0
    blast_radius=0
    gravity=0
    isjumping=False
    isducking=False
    level=None
    direction=None

    def __init__(self,argwindow,argsheight,argswidth,argcolor=white,argwidth=40,argheight=60,argx=0,argy=0,argball_damage=5,argbomb_damage=15,argbomb_radius=10,argchrono_level=500):
        ## Constructor. Pass in the color, width, and height
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.Surface([argwidth,argheight])
        self.image.fill(argcolor)
        self.rect=self.image.get_rect()
        ## sets up the variables inital variables
        self.window=argwindow
        self.width=argwidth
        self.height=argheight
        self.screen_height=argsheight
        self.screen_width=argswidth
        self.rect.x=argx
        self.rect.y=argy
        self.x_velocity=0
        self.y_velocity=0
        self.ball_damage=argball_damage
        self.bomb_damage=argbomb_damage
        self.bomb_radius=argbomb_radius
        self.chrono_level=argchrono_level
        self.isjumping=False
        self.isducking=False

    def update(self):
        ## check gravity
        self.calc_grav()
        ## move left or right
        self.rect.x+=self.x_velocity
        ## check for any collisions
        platform_hit_list=pygame.sprite.spritecollide(self,self.level.platform_list,False)## this is the pygame generatred collision detection builtin to the sprite class
        for platform in platform_hit_list:
            if self.x_velocity > 0:##i.e sprite was moving right
                self.rect.right = platform.rect.left ##puts the right side of the sprite flush with the left side of the platform
            elif self.x_velocity < 0:
                self.rect.left = platform.rect.right  
            self.x_velocity=0           
        ## move sprite up or down
        self.rect.y+=self.y_velocity
        ## check for any collisions
        platform_hit_list=pygame.sprite.spritecollide(self,self.level.platform_list,False)## this is the pygame generatred collision detection builtin to the sprite class
        for platform in platform_hit_list:
            if self.y_velocity > 0:## i.e. sprite is falling
                self.rect.bottom = platform.rect.top ## puts bottom of player flush with top of platform
                self.isjumping=False
            elif self.y_velocity < 0:
                self.rect.top = platform.rect.bottom
            self.y_velocity=0
        ## check direction
        pos = pygame.mouse.get_pos()
        if pos[0] > (self.rect.x+(self.width/2)): ##i.e. cursor is farther to the right then the middle of the sprite
            self.direction="Right"
        else: ##pos[0] < (self.rect.x+(self.width/2))
            self.direction="Left"
    def jump(self):
        if not self.isjumping:
            self.y_velocity=-15
            self.isjumping=True

    def calc_grav(self):
        if self.y_velocity ==0:
            self.y_velocity=1
        else:
            self.y_velocity+=self.gravity

        if self.rect.y >= self.screen_height - self.rect.height and self.y_velocity >= 0:
            self.y_velocity = 0
            self.rect.y = self.screen_height - self.rect.height
            self.isjumping=False

    def move_left(self):## called if the player hits the left arrow key or the a key
        self.x_velocity=-5

    def move_right(self):## called is the player hits the right arrow key or the d key
        self.x_velocity=5

    def stop(self):## called if the player lets up on either arrow key or the a or d key
        self.x_velocity=0

    def shoot(self,argmouse_position):
        if self.direction=="Left":
            bullet_start_x=self.rect.x
            bullet_start_y=(self.rect.y+(self.height/2))
        elif self.direction=="Right":
            bullet_start_x=(self.rect.x+self.width)
            bullet_start_y=(self.rect.y+(self.height/2))
        bullet=player_bullet(bullet_start_x,bullet_start_y,argmouse_position)
        return (bullet)


class player_bullet(pygame.sprite.Sprite):

    bullet_x=None
    bullet_y=None
    bullet_x_velocity=None
    bullet_y_velocity=None
    target_x=None
    target_y=None
    speed=10

    def __init__(self,argx,argy,argmouse_positon):
        pygame.sprite.Sprite.__init__(self)
        print "it inited"
        self.image = pygame.Surface([4, 10])
        self.image.fill(black)
        self.rect=self.image.get_rect()
        self.rect.x=argx
        self.rect.y=argy
        self.bullet_x=argx
        self.bullet_y=argy
        self.target_x=argmouse_positon[0]
        self.target_y=argmouse_positon[1]
        dx=self.target_x-self.bullet_x
        dy=self.target_y-self.bullet_y
        angle=math.atan2(dy,dx)
        print angle
        self.bullet_x_velocity=self.speed*math.cos(angle)
        self.bullet_y_velocity=self.speed*math.sin(angle)
    def update(self):
        print self.rect.x
        print self.bullet_x_velocity
        self.rect.x+=self.bullet_x_velocity
        print self.rect.x
        self.rect.y+=self.bullet_y_velocity
    def collide(self,argdisplay_width,argdisplay_height,argplatform_list):
        Platform_hit_list=pygame.sprite.spritecollide(self, argplatform_list, False)
        if len(Platform_hit_list) > 0:
            return True
        elif self.rect.x > argdisplay_width or self.rect.x < 0:
            return True
        elif self.rect.y > argdisplay_height or self.rect.y < 0:
            return True
        else:
            return False

0 个答案:

没有答案