当球撞击墙壁时在python游戏中更改颜色

时间:2018-10-27 20:00:06

标签: python

import pygame
import sys
import numpy as np
import random as rn

pygame.init()

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

class Rectangle:

    def __init__(self,color,loc):
        self.loc = loc
        self.color = color

    def my_draw(self,screen):
        pygame.draw.rect(screen, self.color, self.loc)

    def my_move(self,xoffset,yoffset):
        self.loc = [self.loc[0]+xoffset,self.loc[1]+yoffset] + self.loc[2:]


size = [300, 300]
screen = pygame.display.set_mode(size)
pygame.display.set_caption("C200 CHANGE")


r = Rectangle(RED, [0, 0, 20, 20])


while True:

    pygame.time.wait(40)

    for event in pygame.event.get(): 
        if event.type == pygame.QUIT: 
            pygame.quit()
            sys.exit()

    screen.fill(WHITE)

    r.my_draw(screen)

    if r.loc[0] > 280:
        xd = -rn.randint(1,3)
    if r.loc[1] > 280:
        yd = -rn.randint(1,3)
    if r.loc[0] < 10:
        xd = rn.randint(1,3)
    if r.loc[1] < 10:
        yd = rn.randint(1,3)
    r.my_move(xd,yd)

    pygame.display.flip()

我想问一个问题,当它反弹并撞到墙壁的edge(left,right)时如何改变颜色。我已经尝试过在r =矩形行中修复代码,但是它显示为黑色,但没有给我任何东西。我也尝试添加r = rectangle line(YELLOW[20,20,0,0]),这给了我xd未定义的错误。

1 个答案:

答案 0 :(得分:0)

为了回答您的问题,我将从简化版本开始。 因此,您可以看到,唯一讨论矩形颜色的时间是绘制矩形时:pygame.draw.rect(screen, self.color, self.loc)
因此,从逻辑上讲,为了更改矩形的颜色,我们要做的就是更改self.color

这就像重新分配它一样简单:self.color = (R, G, B),其中RGB是3个新的颜色值。我看到您已经定义了一些颜色常量,因此我们将使用它们。

但是,现在,我们必须在与egde碰撞时执行此更改,但是您已经完成了此操作。因此,我们只需添加一个布尔值标志,即可在碰撞后将其设置为True

has_changed_direction = False

然后进入循环:

if r.loc[0] > 280:
    xd = -rn.randint(1,3)
    has_changed_direction = True
if r.loc[1] > 280:
    yd = -rn.randint(1,3)
    has_changed_direction = True
if r.loc[0] < 10:
    xd = rn.randint(1,3)
    has_changed_direction = True
if r.loc[1] < 10:
    yd = rn.randint(1,3)
    has_changed_direction = True
r.my_move(xd, yd, has_changed_direction)

has_changed_direction = False

然后我们修改my_move以适应新的更改:

def my_move(self, xoffset, yoffset, direction_change):
    self.loc = [self.loc[0] + xoffset,self.loc[1] + yoffset] + self.loc[2:]
    # Rect has hit the wall and needs to change color
    if direction_change:
        self.color = rn.choice(COLORS)

这是最终的清理代码,其中的注释说明了每次修改:


编辑 为了进行所需的修改,下面是新代码:

import pygame
import random as rn
# Removed numpy and sys, you didn't use these modules
# so they added useless overhead

pygame.init()

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

class Rectangle:
    def __init__(self, color, loc):
        self.loc = loc
        self.color = color

    def my_draw(self, screen):
        pygame.draw.rect(screen, self.color, self.loc)

    def my_move(self, xoffset, yoffset):
        # It's much clearer to just increment loc with the offsets
        self.loc[0] += xoffset
        self.loc[1] += yoffset

    def set_color(self, new_color):
        # Change rect color to new_color
        self.color = new_color


size = [300, 300]
screen = pygame.display.set_mode(size)
pygame.display.set_caption("C200 CHANGE")

r = Rectangle(RED, [0, 0, 20, 20])

# Object that'll let us limit framerate later on
clock = pygame.time.Clock()

while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            # No need to import sys just to call exit,
            # it's a builtin function
            exit()

    # Replaced time.wait with the function
    # you probably meant to use to limit
    # framerate (FPS), to in this case 60
    clock.tick(60)


    # Every time rect hits a side, change its color
    if r.loc[0] > 280:
        xd = -rn.randint(1, 3)
        r.set_color(RED)
    if r.loc[1] > 280:
        yd = -rn.randint(1, 3)
        r.set_color(GREEN)
    if r.loc[0] < 10:
        xd = rn.randint(1, 3)
        r.set_color(BLACK)
    if r.loc[1] < 10:
        yd = rn.randint(1, 3)
        r.set_color(YELLOW)


    r.my_move(xd, yd)

    # Reset for next loop iteration,
    # otherwise the color will be changed
    # every frame
    has_changed_direction = False

    screen.fill(WHITE)
    r.my_draw(screen)

    pygame.display.flip()