Tag Archives: Game Development

Creating a Running Game in VueJS – Part 4 – The Finish Line

This post follows on from a series on creating a game in Vue. If you’d like to start from the beginning, then go here.

In the previous post we refactored the single file index.html that we’d been working on into multiple component files, and created a new Vue templated application.

In this post, we’ll do some further refactoring, and we’ll add a finish line.

Reusing Components

Since we now have components, we should re-use them; otherwise, there’s not much point in them being components. Our Player object is just a game object, and since we now need a second game object, let’s rename Player to GameObject. We can also add an additional property; for now, it will simply allow us to see which object is which:

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

We’ll change the template in App.vue, too:

<template>
    <GameObject
        v-bind:location="playerLocation"
        v-bind:type="player">
    </GameObject>
    <Timer 
        v-bind:seconds="secondsRemaining">
    </Timer>
    <GameObject
        v-bind:location="finishLineLocation"
        v-bind:type="finish-line">
    </GameObject>
</template>

As you can see, we’ve changed the data a little: instead of location we now have two pieces of computed data (in fact one isn’t really computed, but we’ll come back to that later):

computed: {                    
    playerLocation: function() {
        return 'width:10px; height:10px; left:' + this.playerX + 'px; top:' + this.playerY + 'px; border:1px solid #000; position: absolute;';
    },
    finishLineLocation: function() {
        return 'width:3px; height:300px; left:500px; top:50px; border:1px solid #000; position: absolute;';
    },

If you run that now, you’ll see the finish line; but alas we can “run” straight past the finish line and nothing happens!

Collision – have we won, or lost?

The first thing we’ll do here is create a new component: GameFinished. This will simply display some text for now saying whether you won or lost. The code inside the component will be very straightforward:

<template>
  <p>Game is finished, you {{ wonOrLost }}</p>
</template>
<script>
  export default {
    name: 'GameFinished',
    props: {
      isWon: Boolean
    },
    computed: {
      wonOrLost: function() {
        return this.isWon ? "Won" : "Lost";
    }
  }
}
</script>

We’ll need to both import and register the component. If you don’t, you’ll start getting errors such as

error ‘GameFinished’ is defined but never used no-unused-vars

Or:

error ‘GameFinished’ is not defined no-undef

To import the component, you’ll need this in App.vue:

<script>
    import GameObject from './components/GameObject.vue';
    import Timer from './components/Timer.vue';
    import GameFinished from './components/GameFinished.vue';

And registering is done slightly further down:

components: {    
    GameObject,
    Timer,
    GameFinished
},

We’ll add a new data property:

data: function() {                    
    return {
	. . . 
        isGameFinished: false

We’ll add a new computed function that will tell us whether we’ve won:

playerWon: function() {
    return this.isGameFinished && (this.secondsRemaining > 0);
}

And finally, the collision detection. Inside the Update method, we’ll just check the player position against the finish line:

update() {
    this.playerX += this.speed;
    if (this.speed > 0) {
        this.speed -= 0.01;
    } else {
        this.speed = 0;
    }
    this.timeNow = new Date().getTime();
    // Collision check
    if (this.playerX > this.finishLine) {
        this.isGameFinished = true;
    }
}

Where is the finish line?

Our last piece of refactoring will be to set the finish line based on a data property:

data: function() {                    
    return {
        . . . 
        finishLine: 500,

Now let’s tweak out finishLineLocation:

finishLineLocation: function() {
    return 'width:3px; height:300px; left:' + this.finishLine + 'px; top:50px; border:1px solid #000; position: absolute;';
},

In the next post, we’ll tweak the controls a little, and we’ll add some graphics.

Playing with the HTML Canvas Again

I’ve previously written about how you can write games using tools like React. I’ve also written about creating a basic game in Html and Javascript, and things like rotating shapes.

In this post, I’m going to demonstrate a sort of Etch A Sketch type program.

The HTML is very simple here:

<!DOCTYPE html>
<html>
<head>
    <link rel="stylesheet" type="text/css" href="test.css">
    <script src="test.js"></script>
</head>
<body onload="doDrawing()">
    <canvas id="canvas">
    </canvas>
</body>
</html>

Basically just bringing in a Javascript file, CSS and putting a canvas on the screen. I’m also calling a function onload – it’s worth bearing in mind that, as it goes, this won’t resize should you change the size of the browser. If you want that behaviour, then have a look at one of my previous posts mentioned above.

The CSS is even simpler:

* { 
    margin:0; 
    padding:0; 
}
canvas {  
    display: block;    
}

All we’re doing here is removing the default margin, and stopping scroll bars from appearing.

Javascript

The Javascript is where everything is happening; let’s start with some variables:

let x = 10;
let y = 10;
let directionHorizontal = 1;
let directionVertical = 0;

The four variables determine the position that we want to draw in, and which way we’re heading. We can now render this to the screen like this:

const doDrawing = () => {
    var c = document.getElementById("canvas");
    
    c.width = window.innerWidth;
    c.height = window.innerHeight;

    var ctx = c.getContext("2d");
    setInterval(() => {
        ctx.fillRect(x, y, 1, 1);
        x += directionHorizontal;
        y += directionVertical;
    }, 10);
}

The canvas width and height are the first things to note: when I started playing with this, I made the mistake of trying to set this in CSS; if you do, it actually doesn’t change the size of the canvas, but stretches it across the screen; this was the only way that I could get the canvas to display full screen without that stretching effect (if you know another / better way, please say so in the comments!)

Next we get the context from the canvas – this allows us to render to it, and then we simply set-up an interval, and draw a rectangle 1px x 1px each iteration.

Summary

That it – as with previous posts, there’s not a whole lot to using the HTML canvas, but I do like to re-experiment every so often.