我试图移动我的角色,但玩家不会移动
I am trying to move my character but instead of that the player wont move
我正在尝试移动我的角色。我写的就像在教程中一样(https://www.youtube.com/watch?v=FfWpgLFMI7w)。它不起作用。我的角色就是不会动。我也没有看到任何错误!我是否忘记在我的代码中添加一些东西 - 在 KEYDOWN
部分?所以整个代码在这里,但问题可能出在 KEYDOWN
部分或玩家坐标中。这是代码:
import pygame
from pygame.locals import *
pygame.init()
WINDOW_WIDTH = 800
WINDOW_HEIGHT = 600
SURFACE = pygame.HWSURFACE|pygame.DOUBLEBUF|pygame.RESIZABLE
win = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT), SURFACE)
win.fill((0, 180, 210))
pygame.display.set_caption("Baloon War!")
icon = pygame.image.load("Baloon war icon.png")
pygame.display.set_icon(icon)
centre_point = (WINDOW_WIDTH//2, WINDOW_HEIGHT//2)
playerImg = pygame.image.load("RobiS.png")
playerX = 370
playerY = 500
playerX_change = 0
def player(x,y):
win.blit(playerImg, (x, y))
class button():
def __init__(self, color, x, y, width, height, text=''):
self.color = color
self.x = x
self.y = y
self.width = width
self.height = height
self.text = text
def draw(self, win, outline=None):
# Call this method to draw the button on the screen
if outline:
pygame.draw.rect(win, outline, (self.x - 2, self.y - 2, self.width + 4, self.height + 4), 0)
pygame.draw.rect(win, self.color, (self.x, self.y, self.width, self.height), 0)
if self.text != '':
font = pygame.font.SysFont('comicsans', 60)
text = font.render(self.text, 1, (0, 0, 0))
win.blit(text, (self.x + (self.width / 2 - text.get_width() / 2), self.y + (self.height / 2 - text.get_height() / 2)))
def isOver(self, pos):
# Pos is the mouse position or a tuple of (x,y) coordinates
if pos[0] > self.x and pos[0] < self.x + self.width:
if pos[1] > self.y and pos[1] < self.y + self.height:
return True
return False
def rescale(self):
new_size = int(WINDOW_WIDTH * self.scale_factor)
x, y = self.rect.center
self.image = pygame.transform.smoothscale(self.original, (new_size, new_size))
self.rect = self.image.get_rect()
self.rect.center = (x, y)
def resize_button(self, WINDOW_WIDTH, WINDOW_HEIGHT, x, y):
self.width = WINDOW_WIDTH
self.height = WINDOW_HEIGHT
self.x = x
self.y = y
def redrawMenuWindow():
win.fill((0, 255, 110))
greenButton.draw(win, (0, 0, 0))
redButton.draw(win, (0, 0, 0))
cyanButton.draw(win, (0, 0, 0))
def redrawGameWindow():
win.fill((0, 150, 210))
pygame.draw.rect(win, (0, 250, 110), (0, 450, 800, 250))
win.blit(playerImg, (370, 400))
def redrawShopWindow():
win.fill((200, 100, 30))
greenButton = button((0, 255, 0), 275, 285, 250, 80, "Start")
redButton = button((255, 0, 0), 275, 475, 250, 80, "Quit")
cyanButton = button((20, 210, 180), 275, 380, 250, 80, "Shop")
game_state = "menu"
run = True
while run:
if game_state == "menu":
redrawMenuWindow()
elif game_state == "game":
redrawGameWindow()
elif game_state == "shop":
redrawShopWindow()
pygame.display.update()
for event in pygame.event.get():
pos = pygame.mouse.get_pos()
if event.type == pygame.QUIT:
run = False
pygame.quit()
quit()
elif event.type == pygame.VIDEORESIZE:
WINDOW_WIDTH = event.w
WINDOW_HEIGHT = event.h
win = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT), SURFACE)
greenButton.resize_button(event.w*0.3, event.h*0.3, event.w/2, event.h/2)
if event.type == pygame.MOUSEBUTTONDOWN:
if greenButton.isOver(pos):
print("clicked the button")
game_state = "game"
if redButton.isOver(pos):
print("clicked the 2button")
run = False
pygame.quit()
quit()
if cyanButton.isOver(pos):
print("clicked the 3button")
game_state = "shop"
if event.type == pygame.MOUSEMOTION:
if greenButton.isOver(pos):
greenButton.color = (105, 105, 105)
else:
greenButton.color = (0, 255, 0)
if redButton.isOver(pos):
redButton.color = (105, 105, 105)
else:
redButton.color = (255, 0, 0)
if cyanButton.isOver(pos):
cyanButton.color = (105, 105, 105)
else:
cyanButton.color = (20, 210, 180)
if event.type == pygame.KEYDOWN:
playerX_change = -0.3
print("Left arrow is pressed")
if event.key == pygame.K_RIGHT:
playerX_change = 0.3
print("Right arrow is pressed")
if event.type == pygame.KEYUP:
if event.key == pygame.K_a or event.key == pygame.K_d:
playerX_change = 0.1
print("Keystroke has been released")
pygame.display.update()
playerX += playerX_change
player(playerX, playerY)
pygame.display.update()
请告诉我密码。如果你只是告诉我问题是什么,我可能不知道如何解决它。如果你能告诉我哪里出了问题,然后编写正确的代码(不一定是整个代码,只是我需要的部分),那将是最好的。如果真正的问题是我因为我忘记了什么或打错了字,那么我很抱歉问这个问题。
第一个问题是您在 update()
之后在主循环中绘制 player
,因此它会在您绘制 player
之前更新监视器上的图像。最后它在 fill()
之前绘制播放器,将其从 Surface
中删除,update()
在显示器上显示 Surface
而没有此 player
。
您在 redrawGameWindow
中绘制了第二个玩家(在 update()
之前并且该玩家在屏幕上可见,但是该玩家使用 (370, 400)
所以它永远不会移动。
包含其他更改的完整代码。
一些基于 PEP 8 -- Style Guide for Python Code
的更改
import pygame
#from pygame.locals import * # PEP8: `import *` is not preferred (but you don't even need it
# --- constants --- (UPPER_CASE_NAMES) # PEP8
WINDOW_WIDTH = 800
WINDOW_HEIGHT = 600
SURFACE = pygame.HWSURFACE|pygame.DOUBLEBUF|pygame.RESIZABLE
# --- classes --- (CamerCaseNames) # PEP8
class Button():
def __init__(self, color, x, y, width, height, text=''):
self.color = color
self.x = x
self.y = y
self.width = width
self.height = height
self.text = text
def draw(self, win, outline=None):
# Call this method to draw the button on the screen
if outline:
pygame.draw.rect(win, outline, (self.x - 2, self.y - 2, self.width + 4, self.height + 4), 0)
pygame.draw.rect(win, self.color, (self.x, self.y, self.width, self.height), 0)
if self.text != '':
font = pygame.font.SysFont('comicsans', 60)
text = font.render(self.text, 1, (0, 0, 0))
win.blit(text, (self.x + (self.width / 2 - text.get_width() / 2), self.y + (self.height / 2 - text.get_height() / 2)))
def is_over(self, pos):
# Pos is the mouse position or a tuple of (x,y) coordinates
if pos[0] > self.x and pos[0] < self.x + self.width:
if pos[1] > self.y and pos[1] < self.y + self.height:
return True
return False
def rescale(self):
new_size = int(WINDOW_WIDTH * self.scale_factor)
x, y = self.rect.center
self.image = pygame.transform.smoothscale(self.original, (new_size, new_size))
self.rect = self.image.get_rect()
self.rect.center = (x, y)
def resize_button(self, WINDOW_WIDTH, WINDOW_HEIGHT, x, y):
self.width = WINDOW_WIDTH
self.height = WINDOW_HEIGHT
self.x = x
self.y = y
# --- functions --- (lower_case_names) # PEP8
def player(x,y):
win.blit(playerImg, (x, y))
def redraw_menu_window():
win.fill((0, 255, 110))
green_button.draw(win, (0, 0, 0))
red_button.draw(win, (0, 0, 0))
cyan_button.draw(win, (0, 0, 0))
def redraw_game_window():
win.fill((0, 150, 210))
pygame.draw.rect(win, (0, 250, 110), (0, 450, 800, 250))
win.blit(player_img, (player_x, player_y)) # use playerX, playerY
def redraw_shop_window():
win.fill((200, 100, 30))
# --- main ---
pygame.init()
win = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT), SURFACE)
win.fill((0, 180, 210))
pygame.display.set_caption("Baloon War!")
icon = pygame.image.load("Baloon war icon.png")
pygame.display.set_icon(icon)
#centre_point = (WINDOW_WIDTH//2, WINDOW_HEIGHT//2)
center_point = win.get_rect().center
player_img = pygame.image.load("RobiS.png")
player_x = 370
player_y = 500
player_x_change = 0
green_button = Button((0, 255, 0), 275, 285, 250, 80, "Start")
red_button = Button((255, 0, 0), 275, 475, 250, 80, "Quit")
cyan_button = Button((20, 210, 180), 275, 380, 250, 80, "Shop")
game_state = "menu"
run = True
while run:
# --- draws ---
if game_state == "menu":
redraw_menu_window()
elif game_state == "game":
player_x += player_x_change
redraw_game_window()
elif game_state == "shop":
redraw_shop_window()
pygame.display.update()
for event in pygame.event.get():
pos = pygame.mouse.get_pos()
if event.type == pygame.QUIT:
run = False
pygame.quit()
quit()
elif event.type == pygame.VIDEORESIZE:
WINDOW_WIDTH = event.w
WINDOW_HEIGHT = event.h
win = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT), SURFACE)
greenButton.resize_button(event.w*0.3, event.h*0.3, event.w/2, event.h/2)
elif event.type == pygame.MOUSEBUTTONDOWN: # you can use `elif`
if game_state == "menu":
if green_button.is_over(pos):
print("clicked the button")
game_state = "game"
if red_button.is_over(pos):
print("clicked the 2button")
run = False
pygame.quit()
quit()
if cyan_button.is_over(pos):
print("clicked the 3button")
game_state = "shop"
elif game_state == "shop": # it has to be `elif` because in previous line is `game_state = "shop"` which could run it at once.
game_state = "menu"
elif event.type == pygame.MOUSEMOTION: # you can use `elif`
if game_state == "menu":
if green_button.is_over(pos):
green_button.color = (105, 105, 105)
else:
green_button.color = (0, 255, 0)
if red_button.is_over(pos):
red_button.color = (105, 105, 105)
else:
red_button.color = (255, 0, 0)
if cyan_button.is_over(pos):
cyan_button.color = (105, 105, 105)
else:
cyan_button.color = (20, 210, 180)
elif event.type == pygame.KEYDOWN: # you can use `elif`
if game_state == "game":
if event.key == pygame.K_LEFT:
print("Left arrow is pressed")
player_x_change = -0.3
if event.key == pygame.K_RIGHT:
player_x_change = 0.3
print("Right arrow is pressed")
elif event.type == pygame.KEYUP: # you can use `elif`
if game_state == "game":
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
player_x_change = 0
print("Keystroke has been released")
# -- end ---
顺便说一句: 你应该看到 pygame.Rect()
用来保持位置和大小,它有 rect.right
你可以用它代替 x + width
.并且它有检测碰撞的功能,如果鼠标在按钮上你可以使用它。
编辑: 有更多更改的代码。
我使用 pygame.Rect
来保持位置和大小,并在 Button
中检查碰撞。我还创建了 class Player
并在 class 和 Button
和 Player
中检查了 events
。 类 也有方法 update()
、draw()
、handle_events
,因此您可以将它们保留在列表中或 pygame.sprite.Group
并使用 for
-loop 来执行这些所有对象的函数。
import pygame
# --- constants --- (UPPER_CASE_NAMES) # PEP8
WINDOW_WIDTH = 800
WINDOW_HEIGHT = 600
SURFACE = pygame.HWSURFACE|pygame.DOUBLEBUF|pygame.RESIZABLE
# --- classes --- (CamerCaseNames) # PEP8
class Button():
def __init__(self, color, hover_color, x, y, width, height, text='', outline=None, action=None):
self.normal_color = color
self.hover_color = hover_color
self.color = self.normal_color
self.rect = pygame.Rect(x, y, width, height)
self.text = text
self.rect_outline = self.rect.copy()
self.rect_outline.x -= 2
self.rect_outline.y -= 2
self.rect_outline.width += 4
self.rect_outline.height += 4
self.font = pygame.font.SysFont('comicsans', 60)
self.text_image = self.font.render(self.text, 1, (0, 0, 0))
self.text_rect = self.text_image.get_rect(center=self.rect.center)
self.outline = outline
self.action = action
def draw(self, win):
# Call this method to draw the button on the screen
if self.outline:
pygame.draw.rect(win, self.outline, self.rect_outline, 0)
pygame.draw.rect(win, self.color, self.rect, 0)
if self.text != '':
win.blit(self.text_image, self.text_rect)
def is_over(self, pos):
return self.rect.collidepoint(pos)
def rescale(self):
new_size = int(WINDOW_WIDTH * self.scale_factor)
x, y = self.rect.center
self.image = pygame.transform.smoothscale(self.original, (new_size, new_size))
self.rect = self.image.get_rect(center=(x, y))
def resize_button(self, WINDOW_WIDTH, WINDOW_HEIGHT, x, y):
self.rect.width = WINDOW_WIDTH
self.rect.height = WINDOW_HEIGHT
self.rect.x = x
self.rect.y = y
def handle_event(self, event):
if event.type == pygame.MOUSEBUTTONDOWN:
if self.rect.collidepoint(event.pos):
if self.action:
self.action() # execute callback fuction
if event.type == pygame.MOUSEMOTION:
if self.is_over(event.pos):
self.color = self.hover_color
else:
self.color = self.normal_color
class Player():
def __init__(self, x, y):
#self.image = pygame.image.load("RobiS.png")
self.image = pygame.image.load("Obrazy/images/square-1.png")
self.rect = self.image.get_rect(x=x, y=y)
self.player_x_change = 0
# you need because you use float values to move player but `self.rect` can keep only int values
self.x = x
self.y = y
self.x_change = 0
def draw(self, win):
self.rect.x = int(self.x)
self.rect.y = int(self.y)
win.blit(self.image, self.rect)
def update(self):
self.x += self.x_change
def handle_event(self, event):
if event.type == pygame.KEYDOWN: # you can use `elif`
if event.key == pygame.K_LEFT:
print("Left arrow is pressed")
self.x_change = -0.3
elif event.key == pygame.K_RIGHT:
self.x_change = 0.3
print("Right arrow is pressed")
elif event.type == pygame.KEYUP: # you can use `elif`
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
self.x_change = 0
print("Keystroke has been released")
# --- functions --- (lower_case_names) # PEP8
def redraw_menu_window():
win.fill((0, 255, 110))
green_button.draw(win)
red_button.draw(win)
cyan_button.draw(win)
def redraw_game_window():
win.fill((0, 150, 210))
pygame.draw.rect(win, (0, 250, 110), (0, 450, 800, 250))
player.draw(win)
back_to_menu_button.draw(win)
def redraw_shop_window():
win.fill((200, 100, 30))
back_to_menu_button.draw(win)
def callback_green_button():
global game_state
print("clicked the button")
game_state = "game"
def callback_red_button():
global run
print("clicked the 2button")
run = False
def callback_cyan_button():
global game_state
print("clicked the 3button")
game_state = "shop"
def callback_back_button():
global game_state
print("back button")
game_state = "menu"
# --- main ---
pygame.init()
win = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT), SURFACE)
win.fill((0, 180, 210))
pygame.display.set_caption("Baloon War!")
#icon = pygame.image.load("Baloon war icon.png")
icon = pygame.image.load("Obrazy/images/ball.png")
pygame.display.set_icon(icon)
#centre_point = (WINDOW_WIDTH//2, WINDOW_HEIGHT//2)
center_point = win.get_rect().center
player = Player(370, 500)
green_button = Button((0, 255, 0), (105, 105, 105), 275, 285, 250, 80, "Start", (0, 0, 0), callback_green_button)
red_button = Button((255, 0, 0), (105, 105, 105), 275, 475, 250, 80, "Quit", (0, 0, 0), callback_red_button)
cyan_button = Button((20, 210, 180), (105, 105, 105), 275, 380, 250, 80, "Shop", (0, 0, 0), callback_cyan_button)
back_to_menu_button = Button((20, 210, 180), (105, 105, 105), 275, 380, 250, 80, "BACK", (0, 0, 0), callback_back_button)
game_state = "menu"
run = True
while run:
# --- draws ---
if game_state == "menu":
redraw_menu_window()
elif game_state == "game":
redraw_game_window()
elif game_state == "shop":
redraw_shop_window()
pygame.display.update()
# --- events ---
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
elif event.type == pygame.VIDEORESIZE:
WINDOW_WIDTH = event.w
WINDOW_HEIGHT = event.h
win = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT), SURFACE)
green_button.resize_button(event.w*0.3, event.h*0.3, event.w/2, event.h/2)
if game_state == "menu":
green_button.handle_event(event)
red_button.handle_event(event)
cyan_button.handle_event(event)
elif game_state == "game":
player.handle_event(event)
back_to_menu_button.handle_event(event)
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
game_state = "menu"
elif game_state == "shop":
back_to_menu_button.handle_event(event)
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
game_state = "menu"
# --- updates ---
if game_state == "menu":
#green_button.update()
#red_button.update()
#cyan_button.update()
pass
elif game_state == "game":
player.update()
elif game_state == "shop":
pass
# -- end ---
pygame.quit()
quit()
我正在尝试移动我的角色。我写的就像在教程中一样(https://www.youtube.com/watch?v=FfWpgLFMI7w)。它不起作用。我的角色就是不会动。我也没有看到任何错误!我是否忘记在我的代码中添加一些东西 - 在 KEYDOWN
部分?所以整个代码在这里,但问题可能出在 KEYDOWN
部分或玩家坐标中。这是代码:
import pygame
from pygame.locals import *
pygame.init()
WINDOW_WIDTH = 800
WINDOW_HEIGHT = 600
SURFACE = pygame.HWSURFACE|pygame.DOUBLEBUF|pygame.RESIZABLE
win = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT), SURFACE)
win.fill((0, 180, 210))
pygame.display.set_caption("Baloon War!")
icon = pygame.image.load("Baloon war icon.png")
pygame.display.set_icon(icon)
centre_point = (WINDOW_WIDTH//2, WINDOW_HEIGHT//2)
playerImg = pygame.image.load("RobiS.png")
playerX = 370
playerY = 500
playerX_change = 0
def player(x,y):
win.blit(playerImg, (x, y))
class button():
def __init__(self, color, x, y, width, height, text=''):
self.color = color
self.x = x
self.y = y
self.width = width
self.height = height
self.text = text
def draw(self, win, outline=None):
# Call this method to draw the button on the screen
if outline:
pygame.draw.rect(win, outline, (self.x - 2, self.y - 2, self.width + 4, self.height + 4), 0)
pygame.draw.rect(win, self.color, (self.x, self.y, self.width, self.height), 0)
if self.text != '':
font = pygame.font.SysFont('comicsans', 60)
text = font.render(self.text, 1, (0, 0, 0))
win.blit(text, (self.x + (self.width / 2 - text.get_width() / 2), self.y + (self.height / 2 - text.get_height() / 2)))
def isOver(self, pos):
# Pos is the mouse position or a tuple of (x,y) coordinates
if pos[0] > self.x and pos[0] < self.x + self.width:
if pos[1] > self.y and pos[1] < self.y + self.height:
return True
return False
def rescale(self):
new_size = int(WINDOW_WIDTH * self.scale_factor)
x, y = self.rect.center
self.image = pygame.transform.smoothscale(self.original, (new_size, new_size))
self.rect = self.image.get_rect()
self.rect.center = (x, y)
def resize_button(self, WINDOW_WIDTH, WINDOW_HEIGHT, x, y):
self.width = WINDOW_WIDTH
self.height = WINDOW_HEIGHT
self.x = x
self.y = y
def redrawMenuWindow():
win.fill((0, 255, 110))
greenButton.draw(win, (0, 0, 0))
redButton.draw(win, (0, 0, 0))
cyanButton.draw(win, (0, 0, 0))
def redrawGameWindow():
win.fill((0, 150, 210))
pygame.draw.rect(win, (0, 250, 110), (0, 450, 800, 250))
win.blit(playerImg, (370, 400))
def redrawShopWindow():
win.fill((200, 100, 30))
greenButton = button((0, 255, 0), 275, 285, 250, 80, "Start")
redButton = button((255, 0, 0), 275, 475, 250, 80, "Quit")
cyanButton = button((20, 210, 180), 275, 380, 250, 80, "Shop")
game_state = "menu"
run = True
while run:
if game_state == "menu":
redrawMenuWindow()
elif game_state == "game":
redrawGameWindow()
elif game_state == "shop":
redrawShopWindow()
pygame.display.update()
for event in pygame.event.get():
pos = pygame.mouse.get_pos()
if event.type == pygame.QUIT:
run = False
pygame.quit()
quit()
elif event.type == pygame.VIDEORESIZE:
WINDOW_WIDTH = event.w
WINDOW_HEIGHT = event.h
win = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT), SURFACE)
greenButton.resize_button(event.w*0.3, event.h*0.3, event.w/2, event.h/2)
if event.type == pygame.MOUSEBUTTONDOWN:
if greenButton.isOver(pos):
print("clicked the button")
game_state = "game"
if redButton.isOver(pos):
print("clicked the 2button")
run = False
pygame.quit()
quit()
if cyanButton.isOver(pos):
print("clicked the 3button")
game_state = "shop"
if event.type == pygame.MOUSEMOTION:
if greenButton.isOver(pos):
greenButton.color = (105, 105, 105)
else:
greenButton.color = (0, 255, 0)
if redButton.isOver(pos):
redButton.color = (105, 105, 105)
else:
redButton.color = (255, 0, 0)
if cyanButton.isOver(pos):
cyanButton.color = (105, 105, 105)
else:
cyanButton.color = (20, 210, 180)
if event.type == pygame.KEYDOWN:
playerX_change = -0.3
print("Left arrow is pressed")
if event.key == pygame.K_RIGHT:
playerX_change = 0.3
print("Right arrow is pressed")
if event.type == pygame.KEYUP:
if event.key == pygame.K_a or event.key == pygame.K_d:
playerX_change = 0.1
print("Keystroke has been released")
pygame.display.update()
playerX += playerX_change
player(playerX, playerY)
pygame.display.update()
请告诉我密码。如果你只是告诉我问题是什么,我可能不知道如何解决它。如果你能告诉我哪里出了问题,然后编写正确的代码(不一定是整个代码,只是我需要的部分),那将是最好的。如果真正的问题是我因为我忘记了什么或打错了字,那么我很抱歉问这个问题。
第一个问题是您在 update()
之后在主循环中绘制 player
,因此它会在您绘制 player
之前更新监视器上的图像。最后它在 fill()
之前绘制播放器,将其从 Surface
中删除,update()
在显示器上显示 Surface
而没有此 player
。
您在 redrawGameWindow
中绘制了第二个玩家(在 update()
之前并且该玩家在屏幕上可见,但是该玩家使用 (370, 400)
所以它永远不会移动。
包含其他更改的完整代码。
一些基于 PEP 8 -- Style Guide for Python Code
的更改import pygame
#from pygame.locals import * # PEP8: `import *` is not preferred (but you don't even need it
# --- constants --- (UPPER_CASE_NAMES) # PEP8
WINDOW_WIDTH = 800
WINDOW_HEIGHT = 600
SURFACE = pygame.HWSURFACE|pygame.DOUBLEBUF|pygame.RESIZABLE
# --- classes --- (CamerCaseNames) # PEP8
class Button():
def __init__(self, color, x, y, width, height, text=''):
self.color = color
self.x = x
self.y = y
self.width = width
self.height = height
self.text = text
def draw(self, win, outline=None):
# Call this method to draw the button on the screen
if outline:
pygame.draw.rect(win, outline, (self.x - 2, self.y - 2, self.width + 4, self.height + 4), 0)
pygame.draw.rect(win, self.color, (self.x, self.y, self.width, self.height), 0)
if self.text != '':
font = pygame.font.SysFont('comicsans', 60)
text = font.render(self.text, 1, (0, 0, 0))
win.blit(text, (self.x + (self.width / 2 - text.get_width() / 2), self.y + (self.height / 2 - text.get_height() / 2)))
def is_over(self, pos):
# Pos is the mouse position or a tuple of (x,y) coordinates
if pos[0] > self.x and pos[0] < self.x + self.width:
if pos[1] > self.y and pos[1] < self.y + self.height:
return True
return False
def rescale(self):
new_size = int(WINDOW_WIDTH * self.scale_factor)
x, y = self.rect.center
self.image = pygame.transform.smoothscale(self.original, (new_size, new_size))
self.rect = self.image.get_rect()
self.rect.center = (x, y)
def resize_button(self, WINDOW_WIDTH, WINDOW_HEIGHT, x, y):
self.width = WINDOW_WIDTH
self.height = WINDOW_HEIGHT
self.x = x
self.y = y
# --- functions --- (lower_case_names) # PEP8
def player(x,y):
win.blit(playerImg, (x, y))
def redraw_menu_window():
win.fill((0, 255, 110))
green_button.draw(win, (0, 0, 0))
red_button.draw(win, (0, 0, 0))
cyan_button.draw(win, (0, 0, 0))
def redraw_game_window():
win.fill((0, 150, 210))
pygame.draw.rect(win, (0, 250, 110), (0, 450, 800, 250))
win.blit(player_img, (player_x, player_y)) # use playerX, playerY
def redraw_shop_window():
win.fill((200, 100, 30))
# --- main ---
pygame.init()
win = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT), SURFACE)
win.fill((0, 180, 210))
pygame.display.set_caption("Baloon War!")
icon = pygame.image.load("Baloon war icon.png")
pygame.display.set_icon(icon)
#centre_point = (WINDOW_WIDTH//2, WINDOW_HEIGHT//2)
center_point = win.get_rect().center
player_img = pygame.image.load("RobiS.png")
player_x = 370
player_y = 500
player_x_change = 0
green_button = Button((0, 255, 0), 275, 285, 250, 80, "Start")
red_button = Button((255, 0, 0), 275, 475, 250, 80, "Quit")
cyan_button = Button((20, 210, 180), 275, 380, 250, 80, "Shop")
game_state = "menu"
run = True
while run:
# --- draws ---
if game_state == "menu":
redraw_menu_window()
elif game_state == "game":
player_x += player_x_change
redraw_game_window()
elif game_state == "shop":
redraw_shop_window()
pygame.display.update()
for event in pygame.event.get():
pos = pygame.mouse.get_pos()
if event.type == pygame.QUIT:
run = False
pygame.quit()
quit()
elif event.type == pygame.VIDEORESIZE:
WINDOW_WIDTH = event.w
WINDOW_HEIGHT = event.h
win = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT), SURFACE)
greenButton.resize_button(event.w*0.3, event.h*0.3, event.w/2, event.h/2)
elif event.type == pygame.MOUSEBUTTONDOWN: # you can use `elif`
if game_state == "menu":
if green_button.is_over(pos):
print("clicked the button")
game_state = "game"
if red_button.is_over(pos):
print("clicked the 2button")
run = False
pygame.quit()
quit()
if cyan_button.is_over(pos):
print("clicked the 3button")
game_state = "shop"
elif game_state == "shop": # it has to be `elif` because in previous line is `game_state = "shop"` which could run it at once.
game_state = "menu"
elif event.type == pygame.MOUSEMOTION: # you can use `elif`
if game_state == "menu":
if green_button.is_over(pos):
green_button.color = (105, 105, 105)
else:
green_button.color = (0, 255, 0)
if red_button.is_over(pos):
red_button.color = (105, 105, 105)
else:
red_button.color = (255, 0, 0)
if cyan_button.is_over(pos):
cyan_button.color = (105, 105, 105)
else:
cyan_button.color = (20, 210, 180)
elif event.type == pygame.KEYDOWN: # you can use `elif`
if game_state == "game":
if event.key == pygame.K_LEFT:
print("Left arrow is pressed")
player_x_change = -0.3
if event.key == pygame.K_RIGHT:
player_x_change = 0.3
print("Right arrow is pressed")
elif event.type == pygame.KEYUP: # you can use `elif`
if game_state == "game":
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
player_x_change = 0
print("Keystroke has been released")
# -- end ---
顺便说一句: 你应该看到 pygame.Rect()
用来保持位置和大小,它有 rect.right
你可以用它代替 x + width
.并且它有检测碰撞的功能,如果鼠标在按钮上你可以使用它。
编辑: 有更多更改的代码。
我使用 pygame.Rect
来保持位置和大小,并在 Button
中检查碰撞。我还创建了 class Player
并在 class 和 Button
和 Player
中检查了 events
。 类 也有方法 update()
、draw()
、handle_events
,因此您可以将它们保留在列表中或 pygame.sprite.Group
并使用 for
-loop 来执行这些所有对象的函数。
import pygame
# --- constants --- (UPPER_CASE_NAMES) # PEP8
WINDOW_WIDTH = 800
WINDOW_HEIGHT = 600
SURFACE = pygame.HWSURFACE|pygame.DOUBLEBUF|pygame.RESIZABLE
# --- classes --- (CamerCaseNames) # PEP8
class Button():
def __init__(self, color, hover_color, x, y, width, height, text='', outline=None, action=None):
self.normal_color = color
self.hover_color = hover_color
self.color = self.normal_color
self.rect = pygame.Rect(x, y, width, height)
self.text = text
self.rect_outline = self.rect.copy()
self.rect_outline.x -= 2
self.rect_outline.y -= 2
self.rect_outline.width += 4
self.rect_outline.height += 4
self.font = pygame.font.SysFont('comicsans', 60)
self.text_image = self.font.render(self.text, 1, (0, 0, 0))
self.text_rect = self.text_image.get_rect(center=self.rect.center)
self.outline = outline
self.action = action
def draw(self, win):
# Call this method to draw the button on the screen
if self.outline:
pygame.draw.rect(win, self.outline, self.rect_outline, 0)
pygame.draw.rect(win, self.color, self.rect, 0)
if self.text != '':
win.blit(self.text_image, self.text_rect)
def is_over(self, pos):
return self.rect.collidepoint(pos)
def rescale(self):
new_size = int(WINDOW_WIDTH * self.scale_factor)
x, y = self.rect.center
self.image = pygame.transform.smoothscale(self.original, (new_size, new_size))
self.rect = self.image.get_rect(center=(x, y))
def resize_button(self, WINDOW_WIDTH, WINDOW_HEIGHT, x, y):
self.rect.width = WINDOW_WIDTH
self.rect.height = WINDOW_HEIGHT
self.rect.x = x
self.rect.y = y
def handle_event(self, event):
if event.type == pygame.MOUSEBUTTONDOWN:
if self.rect.collidepoint(event.pos):
if self.action:
self.action() # execute callback fuction
if event.type == pygame.MOUSEMOTION:
if self.is_over(event.pos):
self.color = self.hover_color
else:
self.color = self.normal_color
class Player():
def __init__(self, x, y):
#self.image = pygame.image.load("RobiS.png")
self.image = pygame.image.load("Obrazy/images/square-1.png")
self.rect = self.image.get_rect(x=x, y=y)
self.player_x_change = 0
# you need because you use float values to move player but `self.rect` can keep only int values
self.x = x
self.y = y
self.x_change = 0
def draw(self, win):
self.rect.x = int(self.x)
self.rect.y = int(self.y)
win.blit(self.image, self.rect)
def update(self):
self.x += self.x_change
def handle_event(self, event):
if event.type == pygame.KEYDOWN: # you can use `elif`
if event.key == pygame.K_LEFT:
print("Left arrow is pressed")
self.x_change = -0.3
elif event.key == pygame.K_RIGHT:
self.x_change = 0.3
print("Right arrow is pressed")
elif event.type == pygame.KEYUP: # you can use `elif`
if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
self.x_change = 0
print("Keystroke has been released")
# --- functions --- (lower_case_names) # PEP8
def redraw_menu_window():
win.fill((0, 255, 110))
green_button.draw(win)
red_button.draw(win)
cyan_button.draw(win)
def redraw_game_window():
win.fill((0, 150, 210))
pygame.draw.rect(win, (0, 250, 110), (0, 450, 800, 250))
player.draw(win)
back_to_menu_button.draw(win)
def redraw_shop_window():
win.fill((200, 100, 30))
back_to_menu_button.draw(win)
def callback_green_button():
global game_state
print("clicked the button")
game_state = "game"
def callback_red_button():
global run
print("clicked the 2button")
run = False
def callback_cyan_button():
global game_state
print("clicked the 3button")
game_state = "shop"
def callback_back_button():
global game_state
print("back button")
game_state = "menu"
# --- main ---
pygame.init()
win = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT), SURFACE)
win.fill((0, 180, 210))
pygame.display.set_caption("Baloon War!")
#icon = pygame.image.load("Baloon war icon.png")
icon = pygame.image.load("Obrazy/images/ball.png")
pygame.display.set_icon(icon)
#centre_point = (WINDOW_WIDTH//2, WINDOW_HEIGHT//2)
center_point = win.get_rect().center
player = Player(370, 500)
green_button = Button((0, 255, 0), (105, 105, 105), 275, 285, 250, 80, "Start", (0, 0, 0), callback_green_button)
red_button = Button((255, 0, 0), (105, 105, 105), 275, 475, 250, 80, "Quit", (0, 0, 0), callback_red_button)
cyan_button = Button((20, 210, 180), (105, 105, 105), 275, 380, 250, 80, "Shop", (0, 0, 0), callback_cyan_button)
back_to_menu_button = Button((20, 210, 180), (105, 105, 105), 275, 380, 250, 80, "BACK", (0, 0, 0), callback_back_button)
game_state = "menu"
run = True
while run:
# --- draws ---
if game_state == "menu":
redraw_menu_window()
elif game_state == "game":
redraw_game_window()
elif game_state == "shop":
redraw_shop_window()
pygame.display.update()
# --- events ---
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
elif event.type == pygame.VIDEORESIZE:
WINDOW_WIDTH = event.w
WINDOW_HEIGHT = event.h
win = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT), SURFACE)
green_button.resize_button(event.w*0.3, event.h*0.3, event.w/2, event.h/2)
if game_state == "menu":
green_button.handle_event(event)
red_button.handle_event(event)
cyan_button.handle_event(event)
elif game_state == "game":
player.handle_event(event)
back_to_menu_button.handle_event(event)
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
game_state = "menu"
elif game_state == "shop":
back_to_menu_button.handle_event(event)
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
game_state = "menu"
# --- updates ---
if game_state == "menu":
#green_button.update()
#red_button.update()
#cyan_button.update()
pass
elif game_state == "game":
player.update()
elif game_state == "shop":
pass
# -- end ---
pygame.quit()
quit()