Tag Archives: Graphics

Creating a Running Game in VueJS – Part 5 – Gameplay and Graphics

In this, the fifth and final instalment of my series on creating a game using VueJS, we’re going to improve the gameplay a little, and we’re also going to replace our squares and oblongs with graphics.

If you’re new to this series, I’d encourage you to jump back to the first post.

The code for this post is here.

Gameplay and Tidy up

If you’ve played around with the game, you’ll realise there’s quite an easy way to cheat – if you simply press both keys at the same time, it behaves as though you were pressing the keys in quick succession (which, in fact, you are). Let’s stop that by adding a slight delay.

  
onKeyDown(e) {      
            if (this.lastPressed + 50 > Date.now()) {
                return;
            } else {
                this.lastPressed = Date.now();
            }

lastPressed is just added to the data properties.

Next, you may have noticed that we can run past the finish line, and the game continues after it’s finished… which actually means it’s impossible to win, because if you win, once the time gets to zero, you lose.

We can fix this pretty easily by simply stopping the timer once the game is finished; in App.vue, the update function should have the following code where we check when the player passes the finish line:

if (this.playerX > this.finishLine) {
    this.isGameFinished = true;
    this.playerWon = this.isGameFinished && (this.secondsRemaining > 0);
    clearInterval(this.interval);
}
if (this.secondsRemaining <= 0) {
    this.isGameFinished = true;
    this.playerWon = this.isGameFinished && (this.secondsRemaining > 0);
    clearInterval(this.interval);
}

this.interval is set in the init method:

init() {
    this.interval = setInterval(this.update, 10);
    this.startTime = new Date();
    this.startTime.setSeconds(this.startTime.getSeconds() + 20);
},

The next thing we need is to replace our box with some actual graphics.

Graphics

The principle behind animation (any animation, not just in a game) is that you take a series of still picture, and play them rapidly.

I couldn’t find a spritesheet of anyone running, so I created some images of my own; they look absolutely ridiculous, and are essentially made up from using the filled circle and rounded corner rectangle in paint – but then I never claimed to be any good at graphics art. Anyway, for the purpose of this, I’ve dropped them in the assets folder:

It’s a pretty good bet that you (the reader) is better at graphics art than I am, so I would strongly encourage you to not use my graphics if you’re following along. However, they’re in the GitHub repo if you wish to.

To start with, we’ll need to store the names of the images, and the last time we switched the image; so we’ll add a couple of variables to the App.vue script:

const images = [ "daley-1.png", "daley-2.png", "daley-3.png" ];
let lastSwitch = (new Date()).getTime();

We’ll also need a data property to track which image we’re displaying:

    data: function() {                    
        return {
            . . .
            currentImageIdx: 0            
        };
    },

The next step is to slightly change our GameObject such that we now display an image:

<template>
    <div v-bind:style="location">
        <img v-bind:src="image" />
    </div>
</template>
<script>
export default {
  name: 'GameObject',
  props: {
    type: String,
    location: String,
    image: String
  }
}
</script>

In App.vue we’ll need to bind that image:

<GameObject
    v-bind:location="playerLocation"
    type="player"
    v-bind:image="playerImage">
</GameObject>

And a computed property to return it:

playerImage: function() {                        
    return require("./assets/" + images[this.currentImageIdx]);
},

That’s pretty much it; all that remains is to cycle through the images. I’ve done this in the update method, and tried to make it faster as you run faster:

if (this.speed > 0) {
    const refreshSpeed = 1000 - (this.speed * 3);
    if ((new Date()).getTime() > lastSwitch + refreshSpeed) {
        this.currentImageIdx = 
            (this.currentImageIdx < images.length - 1) 
            ? this.currentImageIdx + 1 : 0;
        lastSwitch = new Date().getTime();
    }
}

It’s not perfect, but it roughly looks like he’s running faster as you move him faster.

Summary

This is going to be the last post of my very poor attempt to recreate the amazing Sprectrum game of my youth. As I said at the start, I always find this a useful way to try to learn a new front-end framework – you need to learn about how and when the screen is rendered, and how it deals with interesting things like displaying graphics, updating data, etc.

Getting Started with iOS for a C# Programmer – Part 6 – Graphics

In this post I set out to create a series of posts that would walk through creating a basic game in Swift. In the post preceding this one I covered collision, and now we are moving on to graphics.

Add Assets

The secret to graphics in Swift seems to be creating assets. If you look to the left hand side of your project, you should see an asset store:

This can be added to:

Create a new image here (in fact, we’ll need two):

Then drag and drop your icons. Mine were kindly provided by my daughter:

Use SKSpriteNode

Once you have an image, it’s a straight-forward process to map it to the game sprite (for which we are currently using a rectangle). As you can see in GameScene.swift, very little actually changes:

    func createAlien(point: CGPoint) -> SKSpriteNode {
        let size = CGSize(width: 40, height: 30)
        
        //let alien = SKShapeNode(rectOf: size)
        let alien = SKSpriteNode(imageNamed: "alienImage")
        alien.size = size
        
        //print(self.frame.minY, self.frame.maxY, self.frame.minX, self.frame.maxX, self.frame.width, self.frame.height)
        alien.position = point
        //alien.strokeColor = SKColor(red: 0.0/255.0, green: 200.0/255.0, blue: 0.0/255.0, alpha: 1.0)
        //alien.lineWidth = 4
        
        alien.physicsBody = SKPhysicsBody(rectangleOf: size)
        
        alien.physicsBody?.affectedByGravity = false
        alien.physicsBody?.isDynamic = true
        
        alien.physicsBody?.categoryBitMask = collisionAlien
        alien.physicsBody?.collisionBitMask = 0
        alien.physicsBody?.contactTestBitMask = collisionPlayer
        
        alien.name = "alien"
        
        return alien

    }
    

It’s worth bearing in mind that this will simply replace the existing rectangles with graphics. As you can probably see from the images above, mine are neither straight, trimmed, nor centered, and so it looks a little skewed in the game. Nevertheless, we’re now in the territory of a playable game:

We’re not there yet, though. The next post is the final one, in which we’ll add a score, deal with the overlapping aliens and probably reduce the size of the ship. Also, if you run this, you’ll see that after a short amount of time, it uses a huge amount of memory tracking all the aliens, so we’ll limit the number of aliens.

References

https://www.raywenderlich.com/49695/sprite-kit-tutorial-making-a-universal-app-part-1

https://developer.apple.com/library/content/documentation/Xcode/Reference/xcode_ref-Asset_Catalog_Format/

https://developer.apple.com/documentation/spritekit/skspritenode