我正在使用PyGame编写一个游戏,并相信所有弹跳球的代码都是一致的。然而,过了一会儿,球以不同的速度反弹。
我的代码是否有误?如果是这样,请你试着找出哪里?如果没有,发生了什么?
由于
我的代码:
"""The IMPOSIBLE GAME"""
#Library
import time
import random
import pygame
import sys
from pygame.locals import *
Cube_x = 1
Cube_y = 1
Cube_x_vel = 0
Cube_y_vel = 0
#Colour Bank
Black = (0,0,0)
White = (255,255,255)
Red = (255,0,0)
Green = (0,255,0)
Blue = (0,0,255)
Dark_Purple = (102,0,102)
Orange = (255,128,0)
#Colour List
colour_list = [Black, White, Red, Blue, Green]
#Controls
UP = 'up'
DOWN = 'down'
LEFT = 'left'
RIGHT = 'right'
#Player Variables
DEATHS = 0
LEVEL = 1
SCORE = LEVEL - 1
#Sphere Coordinates
y_s1 = 0
y_s2 = 0
y_s3 = 0
y_s4 = 0
y_s5 = 0
sphere_vel = 5
#Shapes
def draw_CUBE(screen, colour, Cube_x, Cube_y):
pygame.draw.rect(screen, colour, [Cube_x, Cube_y, 30, 30] ,0)
def draw_SPHERE1(Screen, y_s1):
pygame.draw.ellipse(screen, Blue, [100, y_s1, 30, 30] ,0)
def draw_SPHERE2(Screen, y_s2):
pygame.draw.ellipse(screen, Blue, [200, y_s2, 30, 30] ,0)
def draw_SPHERE3(Screen, y_s3):
pygame.draw.ellipse(screen, Blue, [300, y_s3, 30, 30] ,0)
def draw_SPHERE4(Screen, y_s4):
pygame.draw.ellipse(screen, Blue, [400, y_s4, 30, 30] ,0)
def draw_SPHERE5(Screen, y_s5):
pygame.draw.ellipse(screen, Blue, [500, y_s5, 30, 30] ,0)
pygame.init()
#Window Variables
Cell_Size = 20
screen_width = 700
screen_height = 400
screen = pygame.display.set_mode((screen_width, screen_height))
clock = pygame.time.Clock()
done = False
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
Cube_y_vel = -3
print("up")
if event.key == pygame.K_DOWN:
Cube_y_vel = 3
print("down")
if event.type == pygame.KEYUP:
if event.key == pygame.K_UP:
Cube_y_vel = 0
print("Key Released")
if event.key == pygame.K_DOWN:
Cube_y_vel = 0
print("Key Released")
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RIGHT:
Cube_x_vel = 3
print("up")
if event.key == pygame.K_LEFT:
Cube_x_vel = -3
print("down")
if event.type == pygame.KEYUP:
if event.key == pygame.K_RIGHT:
Cube_x_vel = 0
print("Key Released")
if event.key == pygame.K_LEFT:
Cube_x_vel = 0
print("Key Released")
Cube_y = Cube_y + Cube_y_vel
Cube_x = Cube_x + Cube_x_vel
y_s1 = y_s1 + sphere_vel
if y_s1 > 370:
sphere_vel = sphere_vel * -1
if y_s1 < 0:
sphere_vel = sphere_vel * -1
y_s2 = y_s2 + sphere_vel
if y_s2 > 370:
sphere_vel = sphere_vel * -1
if y_s2 < 0:
sphere_vel = sphere_vel * -1
y_s3 = y_s3 + sphere_vel
if y_s3 > 370:
sphere_vel = sphere_vel * -1
if y_s3 < 0:
sphere_vel = sphere_vel * -1
y_s4 = y_s4 + sphere_vel
if y_s4 > 370:
sphere_vel = sphere_vel * -1
if y_s4 < 0:
sphere_vel = sphere_vel * -1
y_s5 = y_s5 + sphere_vel
if y_s5 > 370:
sphere_vel = sphere_vel * -1
if y_s5 < 0:
sphere_vel = sphere_vel * -1
screen.fill((255,255,255))
colour = random.choice(colour_list)
draw_CUBE(screen, colour, Cube_x, Cube_y)
draw_SPHERE1(screen, y_s1)
draw_SPHERE2(screen, y_s2)
draw_SPHERE3(screen, y_s3)
draw_SPHERE4(screen, y_s4)
draw_SPHERE5(screen, y_s5)
pygame.draw.rect(screen, Green, [90, 400, 100, 100] , 0)
pygame.display.flip()
clock.tick(60)
pygame.quit
答案 0 :(得分:4)
看看y_s1
成为&gt;时会发生什么? 370
:
y_s1 = y_s1 + sphere_vel # 1
if y_s1 > 370:
sphere_vel = sphere_vel * -1 # 2
if y_s1 < 0:
sphere_vel = sphere_vel * -1
y_s2 = y_s2 + sphere_vel # 3
if y_s2 > 370:
sphere_vel = sphere_vel * -1
if y_s2 < 0:
sphere_vel = sphere_vel * -1 # 4
当y_s1
变为375
(#1)时,您将sphere_vel
从5
更改为-5
(#2),因此在第3行更改y_y2
从370
到365
。
所以现在y_s1
总是与y_s2
,ys_3
,ys_4
和ys_5
分开10。
圈子向下移动,y_s2
在某个时间变为-5
(因为10
小于y_s1
)。
因此第4行再次更改sphere_vel
的符号,因此y_s3
,ys_4
和ys_5
从0
更改为5
现在只有y_s2
被10
关闭了,这就是你所看到的。
我建议您使用pygame的Sprite
和Rect
课程来简化您的生活。
这是一个简单的例子,请注意评论:
# The IMPOSIBLE GAME
import random
import pygame
from pygame.color import Color
from pygame.surface import Surface
from pygame.sprite import Sprite, Group
pygame.init()
# note how pygame defines a lot of colors already for you
colour_list = [Color('Black'), Color('White'), Color('Red'), Color('Blue'), Color('Green')]
# we use a dict to keep a simple 'What Key Moves In Which Direction'-map
keys = {pygame.K_UP: ( 0, -3),
pygame.K_DOWN: ( 0, 3),
pygame.K_LEFT: (-3, 0),
pygame.K_RIGHT: ( 3, 0)}
# using sprites will make your live easy
# e.g. you don't need to handle drawing yourself
class Player(Sprite):
def __init__(self):
Sprite.__init__(self)
# we create a simple rectangular surface
self.image = Surface((30, 30))
self.rect = self.image.get_rect()
self.image.fill(Color('Black'))
# we set a colorkey so we can create a mask
# this mask is used for pixel perfect collision
# which will come in handy not only for circles
# but if you extend your game to other shape
self.image.set_colorkey(Color('Purple'))
self.mask = pygame.mask.from_surface(self.image)
self.deaths = 0
def update(self):
# use a random color from the list
self.image.fill(random.choice(colour_list))
# check which keys are pressed
pressed = pygame.key.get_pressed()
for key, movement in keys.iteritems():
if pressed[key]:
# and move our rect in that direction
# note how we don't need extra variables
# the rect is enough
self.rect.move_ip(movement)
# we use the clamp_ip function to ensure your rect
# does not get out of screeen.
self.rect.clamp_ip(pygame.display.get_surface().get_rect())
# check if we collide with any object in the objects group
# we use pygame.sprite.collide_mask to have a pixel perfect
# collision detection
# objects is a global variable, which may bother, but we could
# simply pass it through the update function instead
if pygame.sprite.spritecollide(self, objects, False, pygame.sprite.collide_mask):
self.deaths += 1
self.rect.topleft = (0, 0)
class Circle(Sprite):
def __init__(self, start_x, speed):
Sprite.__init__(self)
# same as the in the Player class
# we create a simple Surface
self.image = Surface((30, 30))
self.rect = self.image.get_rect(x=start_x, y=100)
self.image.fill(Color('Purple'))
self.image.set_colorkey(Color('Purple'))
pygame.draw.ellipse(self.image, Color('Blue'), (0, 0, 30, 30), 0)
self.mask = pygame.mask.from_surface(self.image)
self.y_vel = speed
def update(self):
# we create a rect which will tell us
# were we would move
target = self.rect.move(0, self.y_vel)
# and if we would go out of screen
if not pygame.display.get_surface().get_rect().contains(target):
# we simply change direction
self.y_vel *= -1
# then acutally move
self.rect.move_ip(0, self.y_vel)
screen = pygame.display.set_mode((700, 400))
clock = pygame.time.Clock()
done = False
# When creating the circles, we can specify the start position and speed
objects = Group((Circle(x+100, 5) for x in xrange(0, 500, 100)))
# use a Group to handle updating and drawing
all_group = Group(*objects)
all_group.add(Player())
# your main loop is as easy as this
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
all_group.update()
screen.fill(Color('White'))
all_group.draw(screen)
pygame.display.flip()
clock.tick(60)
pygame.quit()
答案 1 :(得分:0)
原因似乎是两件事。首先是因为你在检查它们是否仍然在屏幕上之前移动球,并且因为你的代码会产生一些时间问题。
我会通过在移动球之前检查并在for循环中一次性绘制球来解决这个问题。
示例:
#Sphere Coordinates
ylist = [0, 0, 0, 0, 0]
sphere_vel = 5
#Shapes
def draw_SPHERE(Screen, x, y):
pygame.draw.ellipse(screen, Blue, [x, y, 30, 30] ,0)
pygame.init()
done = False
while not done:
screen.fill((255,255,255))
for y in range(len(ylist)):
if ylist[y] + sphere_vel > 370 or ylist[y] + sphere_vel < 0:
sphere_vel = sphere_vel * -1
ylist[y] = ylist[y] + sphere_vel
draw_SPHERE(screen, (y+1) * 100, ylist[y])
pygame.display.flip()
clock.tick(60)