简体   繁体   中英

Python Game Movement

I am working on a simulation for a business problem, but I am trying to build a 2d game to demonstrate the simulated movements.

To do this, I am starting off with an actual python game that I found some code for online.

The goal is to create 100s of simulated movements (up, down, left, right, stop) via random integer. For example, random = 1, then move left.

For some reason I am able to send the first movement, but the second to 100th movements are ignored by the game.

Can someone please give me a hint as to what I'm doing wrong?

I would greatly appreciate someone's expertise.

GitHub Link :: https://github.com/deacons2016/pygame

from __future__ import division

import random
from cocos.actions import AccelDeccel
from cocos.actions import Delay
from cocos.actions import JumpBy
from cocos.actions import Move
from cocos.actions import MoveBy
from cocos.actions import Repeat
from cocos.actions import Reverse
from cocos.actions import RotateBy
from pyglet.window import key

import cocos
import cocos.collision_model as cm
import resources
import time


class Game(cocos.layer.ColorLayer):
    is_event_handler = True

    def __init__(self):
        super(Game, self).__init__(102, 102, 225, 255)

        self.collision_manager = cm.CollisionManagerBruteForce()

        self.player = cocos.sprite.Sprite(resources.player)
        self.player.position = 400, 25
        self.player.velocity = 0, 0
        self.player.speed = 150
        self.add(self.player, z=2)

        self.player.cshape = cm.AARectShape(
            self.player.position,
            self.player.width//2,
            self.player.height//2
        )
        self.collision_manager.add(self.player)

        self.boss = cocos.sprite.Sprite(resources.player)
        self.boss.position = 400, 600
        self.boss.scale = 0.4
        self.add(self.boss, z=1)

        self.boss.cshape = cm.AARectShape(
            self.boss.position,
            self.boss.width//2,
            self.boss.height//2
        )
        self.collision_manager.add(self.boss)

        self.batch = cocos.batch.BatchNode()
        self.enemies = [cocos.sprite.Sprite(resources.player)
                        for i in range(6)]
        positions = ((250, 125), (550, 125), (300, 325), (500, 325),
                     (150, 475), (650, 475))
        for num, enem in enumerate(self.enemies):
            enem.position = positions[num]
            enem.cshape = cm.AARectShape(
                enem.position,
                enem.width//2,
                enem.height//2
            )
            self.collision_manager.add(enem)
            self.batch.add(enem)

        self.add(self.batch, z=1)
        self.player.do(Move())

        move_basic = MoveBy((120, 0), 1)
        self.enemies[0].do(Repeat(move_basic + Reverse(move_basic)))
        self.enemies[1].do(Repeat(Reverse(move_basic) + move_basic))

        move_complex = (MoveBy((-75, 75), 1) +
                        Delay(0.5) +
                        MoveBy((-75, -75), 1) +
                        Delay(0.5) +
                        MoveBy((75, -75), 1) +
                        Delay(0.5) +
                        MoveBy((75, 75), 1) +
                        Delay(0.5))
        self.enemies[2].do(Repeat(move_complex))
        self.enemies[3].do(Repeat(Reverse(move_complex)))

        move_jump = AccelDeccel(JumpBy((200, 0), 75, 3, 3))
        move_jump_rot = AccelDeccel(RotateBy(360, 3))
        self.enemies[4].do(Repeat(move_jump + Reverse(move_jump)))
        self.enemies[4].do(Repeat(move_jump_rot + Reverse(move_jump_rot)))
        self.enemies[5].do(Repeat(Reverse(move_jump) + move_jump))
        self.enemies[5].do(Repeat(Reverse(move_jump_rot) + move_jump_rot))

        self.schedule(self.update)

    def simulate(self):
        x = 100
        while x > 0:
            rand = random.randint(1,5)
            if rand == 1:
                self.movePlayer("left")
                time.sleep(.05)
                print("left")
            elif rand == 2:
                self.movePlayer("right")
                time.sleep(.05)
                print("right")
            elif rand == 3:
                self.movePlayer("up")
                time.sleep(.05)
                print("up")
            elif rand == 4:
                self.movePlayer("down")
                time.sleep(.05)
                print("down")

            elif rand == 5:
                self.movePlayer("space")
                time.sleep(.05)
                print("space")
            x -= 1

    def update(self, dt):
        self.player.cshape.center = self.player.position
        for enem in self.enemies:
            enem.cshape.center = enem.position

        collisions = self.collision_manager.objs_colliding(self.player)
        if collisions:
            if self.boss in collisions:
                print("You won!")
            cocos.director.director.pop()

    def movePlayer(self, symbol):

         if symbol == "left":
                self.player.velocity = -self.player.speed, 0
         elif symbol == "right":
                self.player.velocity = self.player.speed, 0
         elif symbol == "up":
                self.player.velocity = 0, self.player.speed
         elif symbol == "down":
                self.player.velocity = 0, -self.player.speed
         elif symbol == "space":
                self.player.velocity = 0, 0


if __name__ == '__main__':
    cocos.director.director.init(
        width=800,
        height=650,
        caption="Catch your husband!"
    )

    game_layer = Game()
    game_scene = cocos.scene.Scene(game_layer)

    game_layer.simulate()

    cocos.director.director.run(game_scene)

    print("after")

Like @Blckknght pointed out, drawing the layer Game and running its other scheduled functions (in your case Game.update ) starts only after calling cocos.director.director.run(game_scene). That is why you cannot see the velocity updates - they are done by the time drawing begins.

You should remove the call game_layer.simulate() as it doesn't have the desired effect.

Then you could do:

def simulate(self, dt):
    if self.x > 0:  # set this to 100 in constructor
        rand = random.randint(1,5)
        if rand == 1:
            self.movePlayer("left")
            print("left")
        elif rand == 2:
            self.movePlayer("right")
            print("right")
        elif rand == 3:
            self.movePlayer("up")
            print("up")
        elif rand == 4:
            self.movePlayer("down")
            print("down")

        elif rand == 5:
            self.movePlayer("space")
            print("space")
        x -= 1

Notice that I removed calls to time.sleep . Not sure if those would cause problems, but it's probably better to call the dedicated schedule_interval (or schedule ) function in cocos2d.

In the constructor of Game :

self.schedule_interval(self.simulate, 0.05)
self.schedule_interval(self.update, 0.05)

To schedule Game.simulate you must change the signature of the function to have dt as its second argument, like Game.update has.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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