-2

So this is my game I've bean working on and so have things are going very well, the player can move around and shoot down the boxes which are ment to be moving but theres these small glitches, but before I go on heres the code:

import pygame, math, random, sys
from pygame import *
import random, math, cmath

pygame.init()

#variables end----------------------------------------------------------------

#imagers
grass = "grass_shit.png" #grass image
player_img = "shithead.png" #player name
ali_img = "shit_head2.png" #alien image
dead_screen = "dead_shit.png"
cross_hair = "crosshair.png"
playButton = "playbutton.png"

#screen
screen = pygame.display.set_mode((850, 640),0,32) #set screen                       
background = pygame.image.load(grass).convert() #load image to screen

health = 100

#mouse things
crosshair = pygame.image.load(cross_hair).convert_alpha()

#variables end----------------------------------------------------------------

pygame.mouse.set_visible(False)

black = ( 0, 0, 0)
white = ( 255, 255, 255)
red = ( 255, 0, 0)
blue = ( 0, 0, 255)

player_x, player_y = 0, 0
move_player_x, move_player_y = 0, 0

move_ali_x, move_ali_y = 0, 0

class Block(pygame.sprite.Sprite):

    def __init__(self, color):

        pygame.sprite.Sprite.__init__(self)

        self.image = pygame.Surface([20, 15])
        self.image.fill(color)

        self.rect = self.image.get_rect()

    def update(self):

        global move_ali_x
        global move_ali_y

        if block.rect.x < player_x:
            move_ali_x =+ 0.05
        elif block.rect.x > player_x:
            move_ali_x =- 0.05
        if block.rect.y < player_y:
            move_ali_y =+ 0.05
        elif block.rect.y > player_y:
            move_ali_y =- 0.05

class Player(pygame.sprite.Sprite):

    def __init__(self):

        pygame.sprite.Sprite.__init__(self)

        self.image = pygame.Surface([20,20])
        self.image.fill(red)

        self.rect = self.image.get_rect()
    def update(self):

        pos = pygame.mouse.get_pos()


        self.rect.x = player_x
        self.rect.y = player_y

class Bullet(pygame.sprite.Sprite):

    def __init__(self, mouse, player):

        pygame.sprite.Sprite.__init__(self)

        self.image = pygame.Surface([4, 10])
        self.image.fill(black)

        self.mouse_x, self.mouse_y = mouse[0], mouse[1]
        self.player = player

        self.rect = self.image.get_rect()

    def update(self):

        speed = 10
        range = 50000
        distance = [self.mouse_x - self.player[0], self.mouse_y - self.player[1]]
        norm = math.sqrt(distance[0] ** 2 + distance[1] ** 2)
        direction = [distance[0] / norm, distance[1] / norm]
        bullet_vector = [direction[0] * speed, direction[1] * speed]


        self.rect.x += bullet_vector[0]
        self.rect.y += bullet_vector[1]

pygame.init()

screen_width = 850
screen_height = 640
screen = pygame.display.set_mode([screen_width,screen_height])

all_sprites_list = pygame.sprite.Group()
block_list = pygame.sprite.Group()
bullet_list = pygame.sprite.Group()

for i in range(5):

    block = Block(blue)

    block.rect.x = random.randrange(screen_width)
    block.rect.y = random.randrange(350)

    block_list.add(block)
    all_sprites_list.add(block)

player = Player()
all_sprites_list.add(player)

done = False

clock = pygame.time.Clock()

score = 0
player.rect.y = 370

# -------- Main Program Loop -----------
while not done:

    # --- Event Processing
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            done = True

        elif event.type == pygame.MOUSEBUTTONDOWN:

            bullet = Bullet(event.pos, [player.rect.x, player.rect.y])

            bullet.rect.x = player.rect.x
            bullet.rect.y = player.rect.y

            all_sprites_list.add(bullet)
            bullet_list.add(bullet)

        if event.type== pygame.KEYDOWN:    
            if event.key==K_a:
                    move_player_x=-4
            elif event.key==K_d:
                    move_player_x=+4
            elif event.key==K_w:
                    move_player_y=-4
            elif event.key==K_s:
                    move_player_y=+4

        if event.type== pygame.KEYUP:
            if event.key==K_a:
                    move_player_x=0
            elif event.key==K_d:
                    move_player_x=0
            elif event.key==K_w:
                    move_player_y=0
            elif event.key==K_s:
                    move_player_y=0

    # --- Game logic

    all_sprites_list.update()

    player_x += move_player_x
    player_y += move_player_y

    block.rect.y += move_ali_y
    block.rect.x += move_ali_x

    for bullet in bullet_list:

        block_hit_list = pygame.sprite.spritecollide(bullet, block_list, True)

        for block in block_hit_list:
            bullet_list.remove(bullet)
            all_sprites_list.remove(bullet)
            score += 1
            print( score )

        if bullet.rect.y < -10:
            bullet_list.remove(bullet)
            all_sprites_list.remove(bullet)

    if player.rect.colliderect(block.rect):
        health =- 35

    mouse_x, mouse_y = pygame.mouse.get_pos()
    mouse_x -= crosshair.get_width() / 2
    mouse_y -= crosshair.get_height() / 2
    screen.blit(background,(0,0))

    all_sprites_list.draw(screen)

    screen.blit(crosshair,(mouse_x, mouse_y))
    pygame.display.flip()
    pygame.display.update()

    clock.tick(20)

pygame.quit()

So glitch number one: only one of the boxers moves, I cant figure out why it only one of them is moving towards the player, all the boxers are meant to move towards the player as this is hoping to become a zombie shooter.

Glitch two: At a random point the box that does move does stops moving in all directions but one, so lets say this happens when the box in in the center of the screen, if the player goes to the left of the box, nothing, but when the player moves to thr right of the player it moves right, but only right not up or down, and this seams to happen at soem point everytime.

Well thats it, hope you can help thanks heaps stackoverflow

4

1 回答 1

0

您的代码应如下所示:

import pygame
from pygame import *

import sys
import math
import random
import cmath

#----------------------------------------------------------------------

BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED   = (255, 0, 0)
BLUE  = (0, 0, 255)

#imagers
IMAGE_GRASS       = "grass_shit.png" #grass image
IMAGE_PLAYER      = "shithead.png"   #player name
IMAGE_ALI         = "shit_head2.png" #alien image
IMAGE_DEAD_SCREEN = "dead_shit.png"
IMAGE_CROSSHAIR   = "crosshair.png"
IMAGE_PLAYBUTTON  = "playbutton.png"
#~ IMAGE_GRASS       = "ball3.png" #grass image
#~ IMAGE_PLAYER      = "ball2.png" #player name
#~ IMAGE_ALI         = "ball3.png" #alien image
#~ IMAGE_DEAD_SCREEN = "ball3.png"
#~ IMAGE_CROSSHAIR   = "ball1.png"
#~ IMAGE_PLAYBUTTON  = "ball3.png"

#----------------------------------------------------------------------

class Block(pygame.sprite.Sprite):

    def __init__(self, color, x, y, player = None):

        pygame.sprite.Sprite.__init__(self)

        self.player = player

        self.image = pygame.Surface([20, 15])
        self.image.fill(color)
        self.rect = self.image.get_rect()
        self.rect.x = x
        self.rect.y = y

        self.move_x = self.move_y = 0

    def update(self):

        if self.player:
            player_x, player_y = self.player.rect.center

            if self.rect.x < player_x:
                self.rect.x += 1
            elif self.rect.x > player_x:
                self.rect.x -= 1

            if self.rect.y < player_y:
                self.rect.y += 1
            elif self.rect.y > player_y:
                self.rect.y -= 1

#----------------------------------------------------------------------

class Player(pygame.sprite.Sprite):

    def __init__(self, screen_rect, x=0, y=0):

        pygame.sprite.Sprite.__init__(self)

        self.image = pygame.Surface([20,20])
        self.image.fill(RED)

        self.rect = self.image.get_rect()
        self.rect.x = x
        self.rect.y = y

        self.min_x = screen_rect.left
        self.min_y = screen_rect.top
        self.max_x = screen_rect.right
        self.max_y = screen_rect.bottom

        self.move_x = self.move_y = 0

        self.health = 100

    def update(self):

        pos = pygame.mouse.get_pos()

        self.rect.x += self.move_x
        self.rect.y += self.move_y

        if self.rect.top < self.min_x:
            self.rect.top = self.min_x
        elif self.rect.bottom > self.max_y:
            self.rect.bottom = self.max_y

        if self.rect.left < self.min_x:
            self.rect.left = self.min_x
        elif self.rect.right > self.max_x:
            self.rect.right = self.max_x

    def event_handler(self, event):

        if event.type == pygame.KEYDOWN:    
            if event.key == pygame.K_a:
                self.move_x = -4
            elif event.key == pygame.K_d:
                self.move_x = +4
            elif event.key == pygame.K_w:
                self.move_y = -4
            elif event.key == pygame.K_s:
                self.move_y = +4

        if event.type == pygame.KEYUP:
            if event.key in (pygame.K_a, pygame.K_d):
                self.move_x = 0
            elif event.key in (pygame.K_w, pygame.K_s):
                self.move_y = 0

#----------------------------------------------------------------------

class Bullet(pygame.sprite.Sprite):

    def __init__(self, start_pos, mouse_pos):

        pygame.sprite.Sprite.__init__(self)

        self.start_rect = start_pos.rect.copy()
        self.mouse_x, self.mouse_y = mouse_pos # mouse[0], mouse[1]

        self.image = pygame.Surface([5, 5])
        self.image.fill(BLACK)      
        self.rect = self.image.get_rect()
        self.rect.centerx = self.start_rect.centerx
        self.rect.centery = self.start_rect.centery

        self.speed = 10
        self.max_range = 50
        self.current_range = 0

        distance_x = self.mouse_x - self.start_rect.centerx
        distance_y = self.mouse_y - self.start_rect.centery

        norm = math.sqrt(distance_x ** 2 + distance_y ** 2)
        direction_x = distance_x / norm
        direction_y = distance_y / norm

        self.bullet_vector_x = direction_x * self.speed
        self.bullet_vector_y = direction_y * self.speed

    def update(self):

        self.current_range += 1

        if self.current_range < self.max_range:
            print self.start_rect.centerx + (self.bullet_vector_x*self.current_range), 
            print self.rect.centerx + self.bullet_vector_x, 

            #self.rect.centerx += self.bullet_vector_x
            self.rect.centerx = self.start_rect.centerx + (self.bullet_vector_x*self.current_range) 

            print self.rect.centerx

            #self.rect.centery += self.bullet_vector_y
            self.rect.centery = self.start_rect.centery + (self.bullet_vector_y*self.current_range)

        else:
            self.kill()

#----------------------------------------------------------------------

class Crosshair(pygame.sprite.Sprite):

    def __init__(self):

        pygame.sprite.Sprite.__init__(self)

        self.image = pygame.image.load(IMAGE_CROSSHAIR).convert_alpha()
        self.rect = self.image.get_rect()

    def update(self):

        mouse_x, mouse_y = pygame.mouse.get_pos()

        self.rect.centerx = mouse_x
        self.rect.centery = mouse_y

    def draw(self, screen):
        screen.blit(self.image,self.rect.topleft)

#----------------------------------------------------------------------

class Background(pygame.sprite.Sprite):

    def __init__(self):

        pygame.sprite.Sprite.__init__(self)

        self.image = pygame.image.load(IMAGE_GRASS).convert_alpha()
        self.rect = self.image.get_rect()

    def draw(self, screen):
        screen.fill((128,128,128))
        screen.blit(self.image,(0,0))

#----------------------------------------------------------------------

class Game():

    def __init__(self):

        pygame.init()

        screen_width = 850
        screen_height = 640

        self.screen = pygame.display.set_mode( (screen_width,screen_height) )

        pygame.mouse.set_visible(False)

        #-----

        self.all_sprites_list = pygame.sprite.Group()
        self.block_list = pygame.sprite.Group()
        self.bullet_list = pygame.sprite.Group()

        # --- create sprites ---

        self.background = Background()

        self.player = Player(self.screen.get_rect(), 0, 370)
        self.all_sprites_list.add(self.player)

        for i in range(5):

            block = Block(BLUE, random.randrange(100, screen_width), random.randrange(10, screen_height-10), self.player)

            self.block_list.add(block)
            self.all_sprites_list.add(block)


        self.crosshair = Crosshair()

        #-----

        font = pygame.font.SysFont("", 72)
        self.text_pause = font.render("PAUSE", -1, RED)
        self.text_pause_rect = self.text_pause.get_rect(center=self.screen.get_rect().center) # center text

        #-----

        self.score = 0


    def bullet_create(self, start_pos, mouse_pos):
        bullet = Bullet(start_pos, mouse_pos)

        self.all_sprites_list.add(bullet)
        self.bullet_list.add(bullet)

    def bullets_update(self):

        for bullet in self.bullet_list:

            block_hit_list = pygame.sprite.spritecollide(bullet, self.block_list, True)

            for block in block_hit_list:
                self.bullet_list.remove(bullet)
                self.all_sprites_list.remove(bullet)
                self.score += 1
                print self.score

                if bullet.rect.y < -10:
                    self.bullet_list.remove(bullet)
                    self.all_sprites_list.remove(bullet)

                if pygame.sprite.collide_rect(self.player, block):
                    self.player.health =- 35

    # -------- Main Program Loop -----------

    def run(self):

        clock = pygame.time.Clock()

        RUNNING = True
        PAUSED  = False

        while RUNNING:

            # --- events ---

            for event in pygame.event.get():

                if event.type == pygame.QUIT:
                    RUNNING = False

                elif event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_ESCAPE:
                        RUNNING = false
                    elif event.key == pygame.K_SPACE:
                        PAUSED = not PAUSED

                elif event.type == pygame.MOUSEBUTTONDOWN:
                    self.bullet_create(self.player, event.pos)

                # send event to player
                self.player.event_handler(event)

                # send event to crosshair for mousebuttondown
                #if not PAUSED:
                #   self.crosshair.event_handler(event)

            # --- updates ---

            if not PAUSED:
                self.all_sprites_list.update()
                self.bullets_update()

            self.crosshair.update()

            # --- draws ---

            self.background.draw(self.screen)

            self.all_sprites_list.draw(self.screen)

            self.crosshair.draw(self.screen)

            if PAUSED:
                self.screen.blit(self.text_pause, self.text_pause_rect.topleft)

            pygame.display.update() # use flip() OR update()

            # --- FPS ---

            clock.tick(20)

        # --- quit ---

        pygame.quit()

#----------------------------------------------------------------------

Game().run()

变化:

  • 玩家可以移动但可以离开屏幕
  • 按下space暂停游戏 - 但您仍然可以移动光标并开火 :)
  • 子弹有最大范围 - 比它被删除
  • 我更改了子弹矢量计算,因为每帧的值都被四舍五入为整数并且子弹轨迹不正确
  • 玩家移动时子弹永远不会改变轨迹
  • 除了一些常量值之外,所有代码都在类中。我添加类十字准线和背景
  • 您可以在 event_handle 中看到类(播放器)如何处理事件
  • 我使用 pygame.Rect() (screen.get_rect(), image.get_rect()) 来获取 rect.top、rect.left、rect.center、rect.centerx、rect.topleft 等。

还有很多事情要做。

附言。如果有人需要图像 'ball1.png'、'ball2.png'、'ball3.png' 来运行此示例,您可以在回答

于 2013-11-14T17:58:39.213 回答