Advertisement

Trying to add features to this game (HTML5/Javascript)

Started by April 02, 2014 08:16 PM
1 comment, last by SnakeM120 10 years, 9 months ago

Hello everyone

Im doing this RPG game for a schooling we are doing at work. I was given this started project and added some collission. But i wish to add some more space to it, like the camera should follow the player and the map should be abit bigger. Then you may see in the following code that i also tried to add some tilemap. But i failed miserable at that, so i tried making playing around how to make the world bigger. And even with that im having a hard time. Might anyone help me with this?

Javascript


// Create the canvas
var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
canvas.width = 512;
canvas.height = 480;
document.body.appendChild(canvas);
//ctx.fillStyle = "#FF0000";
/*ctx.rect(0,0,512,480);
ctx.lineWidth = 7;
ctx.strokeStyle = 'black';
ctx.stroke();*/


var mapArray=
[
	[0,0,0,0,1,0,0,0,0,0,0],
	[0,0,0,0,0,0,0,0,0,0,0],
	[0,0,0,0,0,1,0,0,0,0,0],
	[0,0,0,0,0,0,0,0,0,0,0],
	[0,0,0,0,0,0,0,0,0,0,0],
	[0,0,0,0,0,0,0,0,0,0,0]
];


var grass = new Image();
var sand = new Image();

grass.src='images/grass.jpg';
sand.src='images/sand.jpg';




// Background image
var bgReady = false;
var bgImage = new Image();
bgImage.onload = function () {
	bgReady = true;
};

bgImage.src = "images/background.png";

// Hero image
var heroReady = false;
var heroImage = new Image();
heroImage.onload = function () {
	heroReady = true;
};
heroImage.src = "images/hero.png";

// Monster image
var monsterReady = false;
var monsterImage = new Image();
monsterImage.onload = function () {
	monsterReady = true;
};
monsterImage.src = "images/monster.png";

// Game objects
var hero = {
	speed: 256 ,// movement in pixels per second
	color: "#00A",
	x: 220,
	y: 270,
	width: 32,
	height: 32,
	draw: function(){
		ctx.fillStyle = this.color;
		ctx.fillRect(this.x, thix.y, this.width, this.height);
	}
};

//var heroCollider = new rect(0, 0 ,32 ,32);
var monster = {};
var monstersCaught = 0;
var trap = {};

// Handle keyboard controls
var keysDown = {};

addEventListener("keydown", function (e) {
	keysDown[e.keyCode] = true;
}, false);

addEventListener("keyup", function (e) {
	delete keysDown[e.keyCode];
}, false);

// Reset the game when the player catches a monster
var reset = function () {
	hero.x = canvas.width / 2;
	hero.y = canvas.height / 2;

	// Throw the monster somewhere on the screen randomly
	monster.x = 64 + (Math.random() * (canvas.width - 64));
	monster.y = 64 + (Math.random() * (canvas.height - 64));
	
	trap.x = 32 + (Math.random() * (canvas.width - 64));
	trap.y = 32 + (Math.random() * (canvas.height - 64));
	
};

// Update game objects
var update = function (modifier) {
	if (38 in keysDown) { // Player holding up
		hero.y -= hero.speed * modifier;
	}
	if (40 in keysDown) { // Player holding down
		hero.y += hero.speed * modifier;
	}
	if (37 in keysDown) { // Player holding left
		hero.x -= hero.speed * modifier;
	}
	if (39 in keysDown) { // Player holding right
		hero.x += hero.speed * modifier;
	}
	
	
	
	// Wall Colliders
	if(hero.x < 32)
		hero.x = 32;
	if(hero.y < 32)
		hero.y = 32;
	
	if(hero.x > 448)
		hero.x = 448;
	
	if(hero.y > 416)
		hero.y = 416;
	
	
	/*if(hero.x + hero.width > canvas.width)
		hero.x = canvas.width - hero.width;
	if(hero.y + hero.height > canvas.height)
		hero.y = canvas.height - hero.height;*/
	
	// Are they touching?
	if (
		hero.x <= (monster.x + 32)
		&& monster.x <= (hero.x + 32)
		&& hero.y <= (monster.y + 32)
		&& monster.y <= (hero.y + 32)
	) {
		++monstersCaught;
		reset();
	}
};

// Draw everything
var render = function () {
	var posX=0;
	var posY=0;
	for(var i=0; i < mapArray.lenght; i++){
		for(var j=0; j < mapArray[i].lenght; j++){
			if(mapArray[i][j]==0){
				ctx.drawImage(grass, posX, posY, 32,32);
			}
			if(mapArray[i][j]==1){
				ctx.drawImage(sand, posX, posY, 32,32);
			}
			posX+=32;
		
		}
		posX=0;
		posY+=32;
	}
	
	
	if (bgReady) {
		ctx.drawImage(bgImage, 0, 0);
	}

	
	if (heroReady) {
		ctx.drawImage(heroImage, hero.x, hero.y);
	}

	if (monsterReady) {
		ctx.drawImage(monsterImage, monster.x, monster.y);
	}
	
	/*ctx.rect(0,0,512,480);
	ctx.lineWidth = 60;
	ctx.strokeStyle = 'yellow';
	ctx.stroke();*/
	
	// Score
	ctx.fillStyle = "rgb(250, 250, 250)";
	ctx.font = "24px Helvetica";
	ctx.textAlign = "left";
	ctx.textBaseline = "top";
	ctx.fillText("Goblins caught: " + monstersCaught, 0, 0);
};

// The main game loop
var main = function () {
	var now = Date.now();
	var delta = now - then;

	update(delta / 1000);
	render();

	then = now;
};

// Let's play this game!
reset();
var then = Date.now();
setInterval(main, 1); // Execute as fast as possible

All other files i placed with so you guys can download it.

Thank you for now :) and im happy for every feedback

If you want to make a bigger level, you could use dynamic arrays. (It seems that all arrays in JavaScript are dynamic.) so basically:


var sizeX = 100, sizeY = 100;

var map = new array(sizeX);
for (int i = 0; i < sizeX; i++) {
  map[i] = new array(sizeY);
  for (int j = 0; j < sizeY; j++) {
    map[i][j] = 0;
  }
}

Would make a map 100x100 in size, and you access the values of the map this way: map[x][y]. All the values are initially set to 0.

Then I would perhaps make an array for the tiles:

var tiles = array();

tiles[0] = (Some reference to the image tile, attributes, etc that you need, 0 being 'nothing', 1 being 'grass', 2 being flowers, etc.)

Point is to make a list so that each value in the map array directly maps to the index of the tile table. Example: if map[10][10] returns '4', its tile is retrieved using tile[4].

Just to flesh out my immediate idea.

For your movement, you could have a position x, and y for your character. You also have values for the visible width and height of the visible position of the screen in number of visible tiles, and the top left corner position of this rectangle in the map.

Example:

You have a map sized 100x100. You are positioned at 30x60. The visible width and height is 21 tiles in each dimension, making you see 10 tiles ahead in every direction, not counting the spot you are on. This makes all my coordinates inclusive start and end, meaning that a range from 20 to 40 means 21 tiles. (20 = tile 1, 21 = tile 2 ... 39 = tile 20, 40 = tile 21)

You would then start drawing the map at positions x = 30 - 10 = 20, y = 60 - 10 = 50, and end at x = 30 + 10 = 40, y = 60 + 10 = 70, but you need to check the borders so you don't go past the size of the array in either direction in x and y.

You have to decide on:

1. The character must always be in the centre: this means the border of the map somehow must be allowed to move to the centre.

2. The character is allowed to move around on the map freely without being in the centre, and that moving beyond a certain point bumps the map one or more tiles. This allows the map border to never be drawn inside the visible area, and the character to move all the way to the edge of the screen, when the character reaches the end of the map.

3. Make enough bushes and mountains to never allow the border of the map to come inside of the screen.

Sorry if I am not clear enough, I just brainstormed a bit here. Just ask if anything is unclear. smile.png

Edit: I also think that reading about prototypes in JavaScript will come in handy too. That will allow you to do some class/object oriented-like kind of things that you can use for the tiles like:


var tile = function()
{
this.fileName = 0;
this.solid = false;
this.somethingelsethatyouneed = something;
}

tile[0] = new tile;
tile[0].filename = 'somefile';

etc...

I am not sure if this is the best way, but you get the idea. If you want to see the details how I did something similar, view the source code of:

http://stonearts.org/jsgame/3/

I even started on a tile editor once that I never finished because I needed to do some major restructuring to make an effective GUI in JS:

http://stonearts.org/jsgame/1/

(And I really consider myself a n00b...)

Advertisement

If you want to make a bigger level, you could use dynamic arrays. (It seems that all arrays in JavaScript are dynamic.) so basically:


var sizeX = 100, sizeY = 100;

var map = new array(sizeX);
for (int i = 0; i < sizeX; i++) {
  map[i] = new array(sizeY);
  for (int j = 0; j < sizeY; j++) {
    map[i][j] = 0;
  }
}

Would make a map 100x100 in size, and you access the values of the map this way: map[x][y]. All the values are initially set to 0.

Then I would perhaps make an array for the tiles:

var tiles = array();

tiles[0] = (Some reference to the image tile, attributes, etc that you need, 0 being 'nothing', 1 being 'grass', 2 being flowers, etc.)

Point is to make a list so that each value in the map array directly maps to the index of the tile table. Example: if map[10][10] returns '4', its tile is retrieved using tile[4].

Just to flesh out my immediate idea.

For your movement, you could have a position x, and y for your character. You also have values for the visible width and height of the visible position of the screen in number of visible tiles, and the top left corner position of this rectangle in the map.

Example:

You have a map sized 100x100. You are positioned at 30x60. The visible width and height is 21 tiles in each dimension, making you see 10 tiles ahead in every direction, not counting the spot you are on. This makes all my coordinates inclusive start and end, meaning that a range from 20 to 40 means 21 tiles. (20 = tile 1, 21 = tile 2 ... 39 = tile 20, 40 = tile 21)

You would then start drawing the map at positions x = 30 - 10 = 20, y = 60 - 10 = 50, and end at x = 30 + 10 = 40, y = 60 + 10 = 70, but you need to check the borders so you don't go past the size of the array in either direction in x and y.

You have to decide on:

1. The character must always be in the centre: this means the border of the map somehow must be allowed to move to the centre.

2. The character is allowed to move around on the map freely without being in the centre, and that moving beyond a certain point bumps the map one or more tiles. This allows the map border to never be drawn inside the visible area, and the character to move all the way to the edge of the screen, when the character reaches the end of the map.

3. Make enough bushes and mountains to never allow the border of the map to come inside of the screen.

Sorry if I am not clear enough, I just brainstormed a bit here. Just ask if anything is unclear. smile.png

Edit: I also think that reading about prototypes in JavaScript will come in handy too. That will allow you to do some class/object oriented-like kind of things that you can use for the tiles like:


var tile = function()
{
this.fileName = 0;
this.solid = false;
this.somethingelsethatyouneed = something;
}

tile[0] = new tile;
tile[0].filename = 'somefile';

etc...

I am not sure if this is the best way, but you get the idea. If you want to see the details how I did something similar, view the source code of:

http://stonearts.org/jsgame/3/

I even started on a tile editor once that I never finished because I needed to do some major restructuring to make an effective GUI in JS:

http://stonearts.org/jsgame/1/

(And I really consider myself a n00b...)

Ah Thx for the Replys :) Im very Thankfull for your feedback and im Sorry that i haven't replied back in such a long time. Been to busy with Work and my Personal Life.

Anyways to the code, i been trying out the things you been telling me and it seems to quite frankly work properly. I will continue evolving the game and will contact you if there are other types of questiones i have.

This topic is closed to new replies.

Advertisement