[英]Blit object from a Class into a Function (Pygame)
some of you may have seen my previous questions regarding a Pygame project I'm currently working on, but I decided to do a rewrite and follow a proper object oriented programming since it wasn't really working out. 你们中的一些人可能已经看过我以前有关我目前正在从事的Pygame项目的问题,但是我决定重写并遵循正确的面向对象编程,因为它实际上并没有解决。
This is what I have so far: 这是我到目前为止的内容:
###### Import & Init ######
import pygame
import os, random, math, copy, sys
pygame.init()
###### Variables ######
displayWidth, displayHeight = 600, 600
shipWidth, shipHeight = 50, 50
# Variables that will be used to centre the ship.
startX = displayWidth / 2
startY = displayHeight - 40
screen = pygame.display.set_mode((displayWidth, displayHeight))
pygame.display.set_caption('Space Arcader')
####### Colours #######
# Colour list containing most common colours.
# Colour R G B
red = (255, 0, 0)
green = ( 0, 255, 0)
blue = ( 0, 0, 255)
grey = (100, 100, 100)
black = ( 0, 0, 0)
white = (255, 255, 255)
# Create a list from the colours in order to call it later.
colourList = [red, green, blue, black, white]
####### Classes #######
# Ship class
class Ship(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.image.load("assets/ship.png").convert_alpha()
self.image = pygame.transform.scale(self.image,(shipWidth, shipHeight))
self.transform = self.image
self.rect = self.image.get_rect()
self.rect.centerx = startX
self.rect.centery = startY
# Where the arrow will be pointing on game start
self.angle = 90
def update(self, direction):
if direction == 'right' and self.angle > 20:
self.angle -= 4
elif direction == 'left' and self.angle < 160:
self.angle += 4
self.transform = pygame.transform.rotate(self.image, self.angle)
self.rect = self.transform.get_rect()
self.rect.centerx = startX
self.rect.centery = startY
def draw(self):
screen.blit(self.transform, self.rect)
# Score class
class Score(object):
def __init__(self):
self.total = 0
self.font = pygame.font.SysFont('Helvetica', 15)
self.render = self.font.render('Score: ' + str(self.total), True, white)
self.rect = self.render.get_rect()
self.rect.left = 5
self.rect.bottom = displayHeight - 2
self.render.set_colorkey((0,0,0))
def update(self, delete_scoreList):
self.total += ((len(delete_scoreList)) * 50)
self.render = self.font.render('Score: ' + str(self.total), True, white)
def draw(self):
screen.blit(self.render, self.rect)
# Game class
class MainGame(object):
def __init__(self):
self.score = 0
self.game_over = False
def controls(self):
for event in pygame.event.get():
if event.type == pygame.QUIT:
Menu.terminate()
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
direction = 'left'
elif event.key == pygame.K_RIGHT:
direction = 'right'
elif event.type == pygame.KEYUP:
direction = None
if event.key == pygame.K_SPACE:
bullet = Bullet()
bullet.rect.x = arrow.rect.x
bullet.rect.y = arrow.rect.y
all_sprites_list.add(bullet)
bulletList.add(bullet)
elif event.key == pygame.K_ESCAPE:
running = False
MenuInit()
def displayInit(self, screen):
# Set screen width and height.
display = pygame.display.set_mode((displayWidth, displayHeight))
# Set the background image of the window.
background = pygame.image.load("assets/background.jpg")
# Blit the background onto the screen.
screen.blit(background, (0, 0))
# Disable mouse visibility.
pygame.mouse.set_visible(False)
# Code to redraw changing/moving objects.
pygame.display.flip()
# Menu class
class Menu:
hovered = False
def __init__(self, text, pos):
self.text = text
self.pos = pos
self.set_rect()
self.draw()
def draw(self):
self.set_rend()
screen.blit(self.rend, self.rect)
def set_rend(self):
menu_font = pygame.font.SysFont('Helvetica', 40)
self.rend = menu_font.render(self.text, True, self.get_color())
def get_color(self):
if self.hovered:
return (white)
else:
return (grey)
def set_rect(self):
self.set_rend()
self.rect = self.rend.get_rect()
self.rect.topleft = self.pos
def terminate():
pygame.quit()
sys.exit()
####### Functions #######
def MenuInit():
# Set the background image of the window.
background = pygame.image.load("assets/menuBackground.jpg")
options = [Menu("Start game", (200, 250)), Menu("Quit", (265, 300))]
# Enable mouse visibility.
pygame.mouse.set_visible(True)
while True:
for option in options:
if option.rect.collidepoint(pygame.mouse.get_pos()):
option.hovered = True
else:
option.hovered = False
option.draw()
for event in pygame.event.get():
if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
for option in options:
if option.hovered and option.text == "Start game":
MainInit()
elif option.hovered and option.text == "Quit":
Menu.terminate()
pygame.display.update()
screen.blit(background,(0,0))
def MainInit():
# Manage the refresh rate
clock = pygame.time.Clock()
# Loop the game until the user closes the application.
running = True
# Open an instance of the Game class
game = MainGame()
ship = Ship()
score = Score()
# Main Loop.
while running:
draw = ship.draw()
ship.update(direction)
# ship.update(direction)
# ship.draw()
controls = game.controls()
game.displayInit(screen)
# Refresh rate speed (frames per second).
clock.tick(60)
# Open the menuInit() function which brings up the main menu.
if __name__ == '__main__':
MenuInit()
So my problem is trying to blit the ship and score onto the MainInit() function which calls the game class object as you can see above. 所以我的问题是试图弄乱飞船并得分到MainInit()函数上,该函数调用游戏类对象,如上所示。 Calling the game class object works fine because the background image changes and the controls work perfectly.
调用游戏类对象可以正常工作,因为背景图像会更改并且控件可以正常工作。 However, when I follow the same method for ship and score, it doesn't seem to work.
但是,当我采用相同的方法进行评分时,它似乎不起作用。 In the commented out comments, you can see I tried a few things but I got various errors such as
"NameError: global name 'direction' is not defined"
or NameError: global name 'update' is not defined
在注释掉的注释中,您可以看到我尝试了一些操作,但是遇到了各种错误,例如
"NameError: global name 'direction' is not defined"
或NameError: global name 'update' is not defined
"NameError: global name 'direction' is not defined"
NameError: global name 'update' is not defined
Any pointers? 有指针吗? :)
:)
Thank you very much. 非常感谢你。
The problem is caused by an out-of-scope variable - exactly as the error is telling you: global name 'direction' is not defined"
. 问题是由范围外的变量引起的-正是错误告诉您:
global name 'direction' is not defined"
。
You use direction
in your def MainInit()
, but direction
is never defined in that function. 您可以使用
direction
在您的def MainInit()
但direction
是从未在函数定义。 The place you define/set a direction
-variable, is in class MainGame.controls()
. 您定义/设置
direction
可变的位置位于class MainGame.controls()
。
The problem is, however, that the direction
-variable created in class MainGame.controls()
is local only. 问题是,然而,该
direction
在-variable创建class MainGame.controls()
仅局部的 。 It will only exist within that specific function, MainGame.controls()
. 它只会存在于该特定函数
MainGame.controls()
。 When that function is not used any longer, the value of direction
will cease to exist - which is why there is no such thing as direction
defined in def MainInit()
. 当不再使用该函数时,
direction
的值将不复存在-这就是为什么在def MainInit()
不存在诸如direction
这样的东西的原因。 It's out of scope . 这超出范围 。
To fix this problem, you can choose to use direction
as a global variable. 若要解决此问题,您可以选择将
direction
用作全局变量。 It requires you to define the direction
value outside any functions, so at the very beginning should work. 它要求您在任何功能之外定义
direction
值,因此一开始就应该起作用。
Whenever you want to read/modify that specific global variable, you should use the global
keyword, to tell your Python function that you want to use/modify a global variable, and not a local one 每当您要读取/修改特定的全局变量时,都应该使用
global
关键字,以告诉您的Python函数您要使用/修改全局变量,而不是局部变量。
global direction
This might be of interest to you: https://stackoverflow.com/questions/423379/using-global-variables-in-a-function-other-than-the-one-that-created-them 您可能对此很感兴趣: https : //stackoverflow.com/questions/423379/using-global-variables-in-a-function-other-than-the-one-that-created-them
Personally I would not use global variables, but rather store a direction
member variable in the Ship
-class and directly change that. 我个人不会使用全局变量,而是将
direction
成员变量存储在Ship
类中并直接对其进行更改。
Global variables can become quite a mess. 全局变量可能变得一团糟。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.