|
| 1 | +# Imports as usual |
| 2 | +import cocos |
| 3 | +from cocos.sprite import Sprite |
| 4 | +from cocos.tiles import load |
| 5 | +from cocos.layer import ScrollingManager, ScrollableLayer |
| 6 | +from cocos.director import director |
| 7 | +from cocos.scene import Scene |
| 8 | +from cocos.actions import Driver |
| 9 | +from pyglet.window import key |
| 10 | + |
| 11 | +# Let's make a simple game where you drive around a track in a car |
| 12 | +# This code is a simplified version of the one that exists in the cocos examples |
| 13 | + |
| 14 | +# The first thing I need to do is initialize the director, because many other objects in this program depend on it |
| 15 | +# This time I'm going to pass in a few more parameters than usual into the initialize function |
| 16 | +director.init(width=800, height=600, autoscale=False, resizable=True) # I simply set an X and Y for the window, and allow it to be resized |
| 17 | + |
| 18 | +# Here I set a scroller and a key manager |
| 19 | +# The key manager is something new you haven't seen! |
| 20 | +# It allows me to get the keys being pressed globally. Pretty neat! |
| 21 | +keyboard = key.KeyStateHandler() |
| 22 | + |
| 23 | +# And the scrolling manager like you saw last time |
| 24 | +scroller = ScrollingManager() |
| 25 | + |
| 26 | + |
| 27 | +# Here's something you haven't scene before! |
| 28 | +# We'll be using the Driver class from the "move_actions" provided by Cocos, and editing it slightly for our needs |
| 29 | +# The driver class is built to help make having sprites behave like vehicles much simpler |
| 30 | +class CarDriver (Driver): |
| 31 | + # We don't need to call the init function because the Driver class already does that for us! |
| 32 | + |
| 33 | + # Instead I only want to overload this step function. This is what controls the movement of the sprite |
| 34 | + def step(self, dt): |
| 35 | + # This line might seem pretty complicated, but it's really not at all |
| 36 | + self.target.rotation += (keyboard[key.RIGHT] - keyboard[key.LEFT]) * 100 * dt |
| 37 | + # Essentially what I do here is take the right value minus the left value (remember that moving left is negative) |
| 38 | + # And then I multiply it by 100 so it's more visible, and multiply it by the dt value passed in by the step function |
| 39 | + # Finally, I add it to the rotation of the "target", which would be the sprite we tell to do this action |
| 40 | + |
| 41 | + # Now I'm going to do something very similar for the sprite's acceleration |
| 42 | + self.target.acceleration = (keyboard[key.UP] - keyboard[key.DOWN]) * 350 # See if you can figure this out yourself! |
| 43 | + |
| 44 | + # Next I'm going to make the car stop completely if the space key is held |
| 45 | + if keyboard[key.SPACE]: |
| 46 | + self.target.speed = 0 |
| 47 | + # Pretty easy, huh? |
| 48 | + |
| 49 | + # That's basically it! |
| 50 | + # Now we just need to call the original step function to let it do its magic and then update the scroller |
| 51 | + super(CarDriver, self).step(dt) |
| 52 | + |
| 53 | + # Lastly, this line simply tells the ScrollingManager to set the center to the sprite |
| 54 | + scroller.set_focus(self.target.x, self.target.y) |
| 55 | + |
| 56 | + |
| 57 | +# Now we need to make a layer for the car itself! |
| 58 | +# Remember that the layer needs to be scrollable so that the car can move around the map |
| 59 | +class CarLayer(ScrollableLayer): |
| 60 | + def __init__(self): |
| 61 | + super(CarLayer, self).__init__() |
| 62 | + |
| 63 | + # Here we simply make a new Sprite out of a car image I "borrowed" from cocos |
| 64 | + self.sprite = Sprite("assets/img/car.png") |
| 65 | + |
| 66 | + # We set the position (standard stuff) |
| 67 | + self.sprite.position = 200, 100 |
| 68 | + |
| 69 | + # Oh no! Something new! |
| 70 | + # We set a maximum forward and backward speed for the car so that it doesn't fly off the map in an instant |
| 71 | + self.sprite.max_forward_speed = 200 |
| 72 | + self.sprite.max_reverse_speed = -100 |
| 73 | + |
| 74 | + # Then we add it |
| 75 | + self.add(self.sprite) |
| 76 | + |
| 77 | + # And lastly we make it do that CarDriver action we made earlier in this file (yes it was an action not a layer) |
| 78 | + self.sprite.do(CarDriver()) |
| 79 | + |
| 80 | +# Now to the code that actually runs this game! |
| 81 | +# Here I make a layer out of that CarLayer we defined before |
| 82 | +car_layer = CarLayer() |
| 83 | + |
| 84 | +# Next I load the map of the racetrack just as I did in the last tutorial |
| 85 | +map_layer = load("assets/road_map.tmx")["map0"] |
| 86 | + |
| 87 | +# Then we add them to the ScrollingManager |
| 88 | +scroller.add(map_layer) |
| 89 | +scroller.add(car_layer) |
| 90 | +# Order is important! If we added the car layer first, the map would go on top and you wouldn't see the car |
| 91 | + |
| 92 | +# Then we make a scene out of the scroller (just like we did before) |
| 93 | +scene = Scene(scroller) |
| 94 | + |
| 95 | +# This line is a bit random here but... |
| 96 | +# I also need to push the handlers from the window to the object from Pyglet |
| 97 | +# If I don't, it won't be able to handle the Cocos2D keyboard input! |
| 98 | +director.window.push_handlers(keyboard) |
| 99 | + |
| 100 | +# And finally we run the scene |
| 101 | +director.run(scene) |
| 102 | + |
| 103 | +# Now our games are actually starting to seem like, well, games! |
| 104 | + |
| 105 | + |
0 commit comments