简体   繁体   English

如何防止我的python游戏重复执行,而是继续进行?

[英]How can I prevent my python game from reiterating and instead carry on?

I've made a simple game using pygame and livewires, where a sprite has to avoid falling mushrooms. 我使用pygame和livewires制作了一个简单的游戏,其中精灵必须避免掉下蘑菇。 The number of mushrooms falling at a certain time is meant to increase as the score increases. 在特定时间掉落的蘑菇数量意味着随着分数的增加而增加。 Here is what I mean: 这是我的意思:

from livewires import games,color
import random

games.init(screen_width=633,screen_height=479,fps=50)

class Stick_Man(games.Sprite):
 def update(self):
  self.x=games.mouse.x
  if self.left<0:
      self.left=0

  if self.right>games.screen.width:
      self.right=games.screen.width
  self.check_collision()

 def check_collision(self):
  if self.overlapping_sprites:
   self.over_message()

 def over_message(self):
  b=games.Message(value="Game Over", size=100, color=color.red,x=games.screen.width/2,y=games.screen.height/2,lifetime=250,after_death=games.screen.quit)
  games.screen.add(b)


class Mushroom(games.Sprite):
 score=0
 start=200
 score_required=100
 level=1
 total_score=0
 speed=1
 mushroom=games.load_image("mushroom.jpg")
 x_position=random.randrange(640)

 @staticmethod
 def next_level():
    indicate='Level  ', + Mushroom.level, ' cleared'

    message=games.Message(value=indicate,size=50,color=color.red,x=games.screen.width/2,y=games.screen.height/2, lifetime=150)
    games.screen.add(message)
    Mushroom().score_required+=50

    Mushroom().score-=Mushroom.score_required
    Mushroom().start-=150
    Mushroom().speed+=5
    Mushroom().level+=1

    if Mushroom().start==20:
     Mushroom().start+=10 

 def __init__(self):
   super(Mushroom,self).__init__(image=Mushroom.mushroom,x=games.mouse.x,y=0)

 def update(self):
  self.dy=Mushroom.speed
  self.check()
  self.check2()

 def check(self):
  if self.bottom==games.screen.height:
     self.destroy()
     Mushroom.score+=50
     Mushroom.total_score+=Mushroom.score
  if Mushroom().score==Mushroom.score_required:
     self.next_level()

 def check2(self):   
  if self.top==Mushroom.start:
   self.duplicate()

 def duplicate(self):
      new_mush=Mushroom()
      games.screen.add(new_mush)

background_image=games.load_image("background.jpg",  transparent=False)
games.screen.background=background_image

stickman_image=games.load_image("stickman.png", transparent=True)

stickman=Stick_Man(image=stickman_image,left=1,bottom=480)

games.screen.add(stickman)

games.mouse.is_visible=False

b=Mushroom()
c=Mushroom()
a=Mushroom()
games.screen.add(b)
games.screen.add(a)
games.screen.add(c)
games.screen.event_brab=True

games.screen.mainloop()

The code is pretty self explanatory and whenever one of the mushrooms is equal to start, then a new object is created thus meaning a new mushroom comes in. However, what happens is that code doesn't function properly a second time and the mushrooms don't get faster spawn much faster either. 该代码是很容易解释的,每当一个蘑菇等于开始时,就会创建一个新对象,从而意味着一个新的蘑菇进入。但是,发生的情况是该代码第二次无法正常运行,而蘑菇却无法正常工作。也不会更快地产生。 Also, when the game first starts, the minute the first mushroom hits the bottom it says level one cleared, when it should be after two mushrooms. 同样,当游戏第一次开始时,第一个蘑菇到达底部的那一刻,它说级别1已清除,应该在两个蘑菇之后。 The sprite is just a red mushroom and also a stickman which can be found on g images if you want to simulate. 精灵只是一个红色的蘑菇,也是一个火柴人,如果要模拟,可以在g图像上找到它。

So my question is how do i make the object's STATS carry on from where it left off whenever another mushroom appears and also display the message at the right time 所以我的问题是,如何使对象的STATS在出现另一个蘑菇时从中断的地方继续进行,并在正确的时间显示消息

Your problem is in all of the lines that look like this: 您的问题出在所有看起来像这样的行中:

Mushroom().score_required+=50

There are a number of problems here, which all together add up to make this have no useful effect: 这里有很多问题,所有这些问题加起来使它没有任何用处:

  • Mushroom() creates a new Mushroom instance (which goes away as soon as this line is done). Mushroom()创建一个新的Mushroom实例(此行完成后即消失)。
  • Assigning (including update-assigning) to an attribute through an instance always creates or updates an instance attribute, even if there was a class attribute of the same name. 通过实例向属性分配(包括更新分配)始终会创建或更新实例属性,即使存在相同名称的类属性也是如此。
  • The += operator doesn't mutate immutable values like integers in-place (because that would be impossible); + =运算符不会就地改变整数之类的不可变值(因为这是不可能的); a += b is effectively the same as a = a + b .* a += b实际上与a = a + b 。*

So, when you put that together, what you're doing is creating a new value equal to Mushroom.score_required + 50 , then assigning that value to a new instance attribute of a temporary instance (which immediately goes away). 因此,当您将它们放在一起时,您正在做的是创建一个等于Mushroom.score_required + 50的新值,然后将该值分配给临时实例的新实例属性(该实例立即消失)。 This has no effect on the class attribute, or on any of the other instances. 这对class属性或任何其他实例没有影响。

You have a related, but different, problem in the lines like this: 您在类似的行中有一个相关但不同的问题:

x_position=random.randrange(640)

Unless you want all of the mushrooms to have the same x_position , this should not be a class attribute, but an instance attribute, and you're going to run into all kinds of strange problems. 除非您希望所有蘑菇都具有相同的x_positionx_position这不应是class属性,而应是instance属性,否则您将遇到各种奇怪的问题。

Storing game stats as class attributes of a random class is a strange thing to do. 将游戏统计信息存储为随机类的类属性是一件奇怪的事情。 There are ways you could make that work, but there's no good reason to even try. 您可以通过多种方法进行这项工作,但没有充分的理由尝试。 Class attributes are useful for constants that all instances of the class might as well share, but they're not useful as a substitute for global variables. 类属性对于类的所有实例都可能共享的常量很有用,但它们不能代替全局变量。

A better design would be something like this: 更好的设计应该是这样的:

class Game(object):
    def __init__(self):
        self.score = 0
        self.start = 200
        self.score_required = 100
        self.level = 1
        self.total_score = 0
    def next_level(self):
        indicate = 'Level  ', + Mushroom.level, ' cleared'
        message =  games.Message(value=indicate, size=50, color=color.red,
                                 x=games.screen.width/2, y=games.screen.height/2,
                                 lifetime=150)
        games.screen.add(message)
        self.score_required += 50
        self.score -= self.score_required
        self.start -= 150
        self.speed += 5
        self.level += 1
        if self.start == 20:
            self.start += 10
     def update_score(self, n):
        game.score += n
        game.total_score += game.score
        if self.score == self.score_required:
            self.next_level()

class Mushroom(games.Sprite):
    mushroom=games.load_image("mushroom.jpg")
    def __init__(self, game):
        self.x_position=random.randrange(640)
        self.game = game
        super(Mushroom,self).__init__(image=Mushroom.mushroom,x=games.mouse.x,y=0)
    def update(self):
        self.dy=Mushroom.speed
        self.check()
        self.check2()
    def check(self):
        if self.bottom == games.screen.height:
            self.destroy()
        game.update_score(50)
    def check2(self):   
        if self.top == Mushroom.start:
            self.duplicate()   
    def duplicate(self):
        games.screen.add(Mushroom(self.game))

game = Game()
games.screen.add(Mushroom(game))
games.screen.add(Mushroom(game))
games.screen.add(Mushroom(game))
games.screen.event_brab=True

* That's not completely true. *这不是完全正确的。 In fact, a = a + b is equivalent to a = a.__add__(b) , while a += b is equivalent to a = a.__iadd__(b) if such a method exists, falling back to __add__ only if it doesn't. 实际上, a = a + b等效于a = a.__add__(b) ,而a += b等效于a = a.__iadd__(b)如果存在),仅当不存在时才回落到__add__没错 For mutable objects like lists, this makes a big difference, because __iadd__ can change self in-place and then return it, meaning you end up assigning the same object back to a that was already there. 对于像列表可变对象,这使得一个很大的区别,因为__iadd__可以改变self就地,然后返回它,这意味着你最终分配相同的对象回到a是已经在那里了。 But for immutable objects, there's no difference. 但是对于不可变的对象,没有区别。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM