Displaying frames properly in JavaScript - javascript

Okay, so I am developing a game in JavaScript. I have organized all the parts of the game in different JavaScript files. So, this is the Player.js file, every time I run this in my browser ( run from a html file of course), I come into this problem where the Player object flickers from a image to a transparent rectangle: heres the code:
function Player() {
this.frames = [];
this.right = true;
this.currentFrame = 0;
this.currentAction = "WALKING";
this.image = new Image();
this.x = 0;
this.y = 0;
this.setPosition = function(x, y) {
this.x = x;
this.y = y;
};
this.setVector = function(x, y) {
this.x += x;
this.y += y;
};
this.setAction = function(action) {
this.currentAction = action;
};
this.setRight = function(bool) {
this.right = bool;
}
this.draw = function(context) {
if(this.right == true) {
if(this.currentAction == "WALKING") {
this.frames = [ "res/playerRight.png" ];
}
} else if(this.right == false) {
if(this.currentAction == "WALKING") {
this.frames = [ "res/playerLeft.png" ];
}
}
if(this.currentFrame < this.frames.length) {
this.currentFrame += 1;
this.image.src = this.frames[this.currentFrame - 1];
context.drawImage(this.image, this.x,
this.y, 32, 32);
} else {
this.currentFrame = 0;
}
};
}
heres some images of what it does:
http://i.stack.imgur.com/1RcOC.png
http://i.stack.imgur.com/fxbNY.png

How about you preload all the images and you choose the correct one in your condition. Currently everytime you set the source the image is reloaded, and you are drawing it before it is ready.
// you can improve this part for your needs
var image1Loaded = false;
var image2Loaded = false;
this.preLoadImages = function (){
this.image1.onload = function (){
image1Loaded = true;
}
this.image2.onload = function (){
image2Loaded = true;
}
this.image1.src = "res/playerRight.png";
this.image2.src = "res/playerLeft.png";
}
now you can use the images directly in your draw method:
this.draw = function(context) {
var currentImage = "image1";
if(this.right == true) {
if(this.currentAction == "WALKING") {
currentImage = "image1";
}
} else if(this.right == false) {
if(this.currentAction == "WALKING") {
currentImage = "image2";
}
}
if(this.currentFrame < this.frames.length) {
this.currentFrame += 1;
var image = this[currentImage];
context.drawImage(image, this.x,
this.y, 32, 32);
} else {
this.currentFrame = 0;
}
};
Just make sure your images are already loaded before using them to draw on the canvas

Here's the bug:
if(this.currentFrame < this.frames.length) {
this.currentFrame += 1;
context.drawImage(); // <---------------- draw an image
} else {
this.currentFrame = 0; // <-------------- draw nothing!
}
So, let's run through this logic shall we. At the moment, frame length is 1.
currentFrame = 0
so we increment currentFrame
we draw the image
currentFrame = 1
currentFrame is not less than frames.length
we do not draw anything
we set current frame to 0
currentFrame = 0
so we increment currentFrame
we draw the image
repeat....
Result: flicker! If frame length is 2 it will flicker 33% of the time, if the frame length is 3 it will flicker 25% of the time etc.
The correct way to handle this:
this.currentFrame += 1;
if(this.currentFrame >= this.frames.length) {
this.currentFrame = 0;
}
this.image.src = this.frames[this.currentFrame]; // **
context.drawImage();
// **note: no need for -1 because currentFrame here is always
// less than frame.length
Or, if you're mathematical:
this.currentFrame = (this.currentFrame + 1) % this.frames.length;
this.image.src = this.frames[this.currentFrame];
context.drawImage();

Related

How would I add a level system for the score increasing?

I am making a slight Tetris remake and I wanted to add a leveling system for when my score reaches, for example, 100, the speed that the blocks go down will also increase. How would I go about doing this? I have the entirety of the javascript code right here so please let me know what I can do to fix it:
//-------------------------------------------------------------------------
// base helper methods
//-------------------------------------------------------------------------
function get(id) { return document.getElementById(id); }
function hide(id) { get(id).style.visibility = 'hidden'; }
function show(id) { get(id).style.visibility = null; }
function html(id, html) { get(id).innerHTML = html; }
function timestamp() { return new Date().getTime(); }
function random(min, max) { return (min + (Math.random() * (max - min))); }
function randomChoice(choices) { return choices[Math.round(random(0, choices.length-1))]; }
if (!window.requestAnimationFrame) { // http://paulirish.com/2011/requestanimationframe-for-smart-animating/
window.requestAnimationFrame = window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(callback, element) {
window.setTimeout(callback, 1000 / 60);
}
}
//-------------------------------------------------------------------------
// game constants
//-------------------------------------------------------------------------
var KEY = { ESC: 27, SPACE: 32, LEFT: 37, UP: 38, RIGHT: 39, DOWN: 40 },
DIR = { UP: 0, RIGHT: 1, DOWN: 2, LEFT: 3, MIN: 0, MAX: 3 },
stats = new Stats(),
canvas = get('canvas'),
ctx = canvas.getContext('2d'),
ucanvas = get('upcoming'),
uctx = ucanvas.getContext('2d'),
speed = { start: 0.6, decrement: 0.005, min: 0.1 }, // how long before piece drops by 1 row (seconds)
nx = 10, // width of tetris court (in blocks)
ny = 20, // height of tetris court (in blocks)
nu = 5; // width/height of upcoming preview (in blocks)
//-------------------------------------------------------------------------
// game variables (initialized during reset)
//-------------------------------------------------------------------------
var dx, dy, // pixel size of a single tetris block
blocks, // 2 dimensional array (nx*ny) representing tetris court - either empty block or occupied by a 'piece'
actions, // queue of user actions (inputs)
playing, // true|false - game is in progress
dt, // time since starting this game
current, // the current piece
next, // the next piece
score, // the current score
vscore, // the currently displayed score (it catches up to score in small chunks - like a spinning slot machine)
rows, // number of completed rows in the current game
step; // how long before current piece drops by 1 row
//-------------------------------------------------------------------------
// tetris pieces
//
// blocks: each element represents a rotation of the piece (0, 90, 180, 270)
// each element is a 16 bit integer where the 16 bits represent
// a 4x4 set of blocks, e.g. j.blocks[0] = 0x44C0
//
// 0100 = 0x4 << 3 = 0x4000
// 0100 = 0x4 << 2 = 0x0400
// 1100 = 0xC << 1 = 0x00C0
// 0000 = 0x0 << 0 = 0x0000
// ------
// 0x44C0
//
//-------------------------------------------------------------------------
var i = { size: 4, blocks: [0x0F00, 0x2222, 0x00F0, 0x4444], color: 'cyan' };
var j = { size: 3, blocks: [0x44C0, 0x8E00, 0x6440, 0x0E20], color: 'blue' };
var l = { size: 3, blocks: [0x4460, 0x0E80, 0xC440, 0x2E00], color: 'orange' };
var o = { size: 2, blocks: [0xCC00, 0xCC00, 0xCC00, 0xCC00], color: 'yellow' };
var s = { size: 3, blocks: [0x06C0, 0x8C40, 0x6C00, 0x4620], color: 'lime' };
var t = { size: 3, blocks: [0x0E40, 0x4C40, 0x4E00, 0x4640], color: 'purple' };
var z = { size: 3, blocks: [0x0C60, 0x4C80, 0xC600, 0x2640], color: 'red' };
var p = { size: 3, blocks: [0x0F00, 0x2222, 0x00F0,], color: 'maroon' };
//------------------------------------------------
// do the bit manipulation and iterate through each
// occupied block (x,y) for a given piece
//------------------------------------------------
function eachblock(type, x, y, dir, fn) {
var bit, result, row = 0, col = 0, blocks = type.blocks[dir];
for(bit = 0x8000 ; bit > 0 ; bit = bit >> 1) {
if (blocks & bit) {
fn(x + col, y + row);
}
if (++col === 4) {
col = 0;
++row;
}
}
}
//-----------------------------------------------------
// check if a piece can fit into a position in the grid
//-----------------------------------------------------
function occupied(type, x, y, dir) {
var result = false
eachblock(type, x, y, dir, function(x, y) {
if ((x < 0) || (x >= nx) || (y < 0) || (y >= ny) || getBlock(x,y))
result = true;
});
return result;
}
function unoccupied(type, x, y, dir) {
return !occupied(type, x, y, dir);
}
//-----------------------------------------
// start with 4 instances of each piece and
// pick randomly until the 'bag is empty'
//-----------------------------------------
var pieces = [];
function randomPiece() {
if (pieces.length == 0)
pieces = [i,i,i,i,j,j,j,j,l,l,l,l,o,o,o,o,s,s,s,s,t,t,t,t,z,z,z,z,p,p,p,p];
var type = pieces.splice(random(0, pieces.length-1), 1)[0];
return { type: type, dir: DIR.UP, x: Math.round(random(0, nx - type.size)), y: 0 };
}
//-------------------------------------------------------------------------
// GAME LOOP
//-------------------------------------------------------------------------
function run() {
showStats(); // initialize FPS counter
addEvents(); // attach keydown and resize events
var last = now = timestamp();
function frame() {
now = timestamp();
update(Math.min(1, (now - last) / 1000.0)); // using requestAnimationFrame have to be able to handle large delta's caused when it 'hibernates' in a background or non-visible tab
draw();
stats.update();
last = now;
requestAnimationFrame(frame, canvas);
}
resize(); // setup all our sizing information
reset(); // reset the per-game variables
frame(); // start the first frame
}
function showStats() {
stats.domElement.id = 'stats';
get('menu').appendChild(stats.domElement);
}
function addEvents() {
document.addEventListener('keydown', keydown, false);
window.addEventListener('resize', resize, false);
}
function resize(event) {
canvas.width = canvas.clientWidth; // set canvas logical size equal to its physical size
canvas.height = canvas.clientHeight; // (ditto)
ucanvas.width = ucanvas.clientWidth;
ucanvas.height = ucanvas.clientHeight;
dx = canvas.width / nx; // pixel size of a single tetris block
dy = canvas.height / ny; // (ditto)
invalidate();
invalidateNext();
}
function keydown(ev) {
var handled = false;
if (playing) {
switch(ev.keyCode) {
case KEY.LEFT: actions.push(DIR.LEFT); handled = true; break;
case KEY.RIGHT: actions.push(DIR.RIGHT); handled = true; break;
case KEY.UP: actions.push(DIR.UP); handled = true; break;
case KEY.DOWN: actions.push(DIR.DOWN); handled = true; break;
case KEY.ESC: lose(); handled = true; break;
}
}
else if (ev.keyCode == KEY.SPACE) {
play();
handled = true;
}
if (handled)
ev.preventDefault(); // prevent arrow keys from scrolling the page (supported in IE9+ and all other browsers)
}
//-------------------------------------------------------------------------
// GAME LOGIC
//-------------------------------------------------------------------------
function play() { hide('start'); reset(); playing = true; }
function lose() { show('start'); setVisualScore(); playing = false; }
function setVisualScore(n) { vscore = n || score; invalidateScore(); }
function setScore(n) { score = n; setVisualScore(n); }
function addScore(n) { score = score + n; }
function clearScore() { setScore(0); }
function clearRows() { setRows(0); }
function setRows(n) { rows = n; step = Math.max(speed.min, speed.start - (speed.decrement*rows)); invalidateRows(); }
function addRows(n) { setRows(rows + n); }
function getBlock(x,y) { return (blocks && blocks[x] ? blocks[x][y] : null); }
function setBlock(x,y,type) { blocks[x] = blocks[x] || []; blocks[x][y] = type; invalidate(); }
function clearBlocks() { blocks = []; invalidate(); }
function clearActions() { actions = []; }
function setCurrentPiece(piece) { current = piece || randomPiece(); invalidate(); }
function setNextPiece(piece) { next = piece || randomPiece(); invalidateNext(); }
function reset() {
dt = 0;
clearActions();
clearBlocks();
clearRows();
clearScore();
setCurrentPiece(next);
setNextPiece();
}
function update(idt) {
if (playing) {
if (vscore < score)
setVisualScore(vscore + 1);
handle(actions.shift());
dt = dt + idt;
if (dt > step) {
dt = dt - step;
drop();
}
}
}
function handle(action) {
switch(action) {
case DIR.LEFT: move(DIR.LEFT); break;
case DIR.RIGHT: move(DIR.RIGHT); break;
case DIR.UP: rotate(); break;
case DIR.DOWN: drop(); break;
}
}
function move(dir) {
var x = current.x, y = current.y;
switch(dir) {
case DIR.RIGHT: x = x + 1; break;
case DIR.LEFT: x = x - 1; break;
case DIR.DOWN: y = y + 1; break;
}
if (unoccupied(current.type, x, y, current.dir)) {
current.x = x;
current.y = y;
invalidate();
return true;
}
else {
return false;
}
}
function rotate() {
var newdir = (current.dir == DIR.MAX ? DIR.MIN : current.dir + 1);
if (unoccupied(current.type, current.x, current.y, newdir)) {
current.dir = newdir;
invalidate();
}
}
//This is how we make the piece drop down and place:
function drop() {
if (!move(DIR.DOWN)) {
addScore(10);
dropPiece();
removeLines();
setCurrentPiece(next);
setNextPiece(randomPiece());
clearActions();
if (occupied(current.type, current.x, current.y, current.dir)) {
lose();
}
}
}
function dropPiece() {
eachblock(current.type, current.x, current.y, current.dir, function(x, y) {
setBlock(x, y, current.type);
});
}
function removeLines() {
var x, y, complete, n = 0;
for(y = ny ; y > 0 ; --y) {
complete = true;
for(x = 0 ; x < nx ; ++x) {
if (!getBlock(x, y))
complete = false;
}
if (complete) {
removeLine(y);
y = y + 1; // recheck same line
n++;
}
}
if (n > 0) {
addRows(n);
addScore(100*Math.pow(2,n-1)); // 1: 100, 2: 200, 3: 400, 4: 800
}
}
function removeLine(n) {
var x, y;
for(y = n ; y >= 0 ; --y) {
for(x = 0 ; x < nx ; ++x)
setBlock(x, y, (y == 0) ? null : getBlock(x, y-1));
}
}
//-------------------------------------------------------------------------
// RENDERING
//-------------------------------------------------------------------------
var invalid = {};
function invalidate() { invalid.court = true; }
function invalidateNext() { invalid.next = true; }
function invalidateScore() { invalid.score = true; }
function invalidateRows() { invalid.rows = true; }
function draw() {
ctx.save();
ctx.lineWidth = 1;
ctx.translate(0.5, 0.5); // for crisp 1px black lines
drawCourt();
drawNext();
drawScore();
drawRows();
ctx.restore();
}
function drawCourt() {
if (invalid.court) {
ctx.clearRect(0, 0, canvas.width, canvas.height);
if (playing)
drawPiece(ctx, current.type, current.x, current.y, current.dir);
var x, y, block;
for(y = 0 ; y < ny ; y++) {
for (x = 0 ; x < nx ; x++) {
if (block = getBlock(x,y))
drawBlock(ctx, x, y, block.color);
}
}
ctx.strokeRect(0, 0, nx*dx - 1, ny*dy - 1); // court boundary
invalid.court = false;
}
}
function drawNext() {
if (invalid.next) {
var padding = (nu - next.type.size) / 2; // half-complete attempt at centering next piece display
uctx.save();
uctx.translate(0.5, 0.5);
uctx.clearRect(0, 0, nu*dx, nu*dy);
drawPiece(uctx, next.type, padding, padding, next.dir);
uctx.strokeStyle = 'black';
uctx.strokeRect(0, 0, nu*dx - 1, nu*dy - 1);
uctx.restore();
invalid.next = false;
}
}
function drawScore() {
if (invalid.score) {
html('score', ("00000" + Math.floor(vscore)).slice(-5));
invalid.score = false;
}
}
function drawRows() {
if (invalid.rows) {
html('rows', rows);
invalid.rows = false;
}
}
function drawPiece(ctx, type, x, y, dir) {
eachblock(type, x, y, dir, function(x, y) {
drawBlock(ctx, x, y, type.color);
});
}
function drawBlock(ctx, x, y, color) {
ctx.fillStyle = color;
ctx.fillRect(x*dx, y*dy, dx, dy);
ctx.strokeRect(x*dx, y*dy, dx, dy)
}
//-------------------------------------------------------------------------
// FINALLY, lets run the game
//-------------------------------------------------------------------------
run();
You have a function called addScore that seems to be used to update the user's score. You could add a conditional block inside this function that will update the game speed when the new score is above the threshold you choose. Alternatively, if you would prefer to keep addScore purely focused on updating the value of the score, you could add this conditional block wherever you're calling addScore.

Animated canvas background flashing?

I'm attempting to make a typing game with moving words on a canvas, which move left to right and lives are lost if they leave the canvas however i'm trying to animate a simple looping background image for my canvas, I have gotten it working and looping and moving left, however for some reason when this is in use my entire canvas is flashing as if it is constantly redrawing in a strange way or something I don't really know.
var canvas;
var canvasContext;
let x=20;
var string;
let score = 0;
let highscore = 0;
var lives = 3;
var WordID;
var difficultyWordID
var bg = new Image();
bg.src = "client/img/stars.jpg";
window.onload = function(){
canvas = document.getElementById('typingCanvas');
var typeval = document.getElementById("typingValue"); //user typed value.
canvasContext = canvas.getContext('2d');
document.getElementById("Button2").style.display = "none";
document.getElementById("gameOver").style.display = "none";
document.getElementById("scoreText").style.display = "none";
let fps=40;
setInterval(function(){
if(x==20){
string = getWord()
}
moveEverything()
drawEverything(x,string);
if (x>900) {
lives--;
} else if (lives<1) {
canvas.style.display="none";
document.getElementById("Button2").style.display = "block";
document.getElementById("GameTable").style.display = "none";
document.getElementById("gameHR2").style.display = "none";
document.getElementById("gameHR3").style.display = "none";
document.getElementById("gameOver").style.display = "block";
document.getElementById("scoreText").style.display = "block";
document.getElementById("GameHeading").textContent = "Results below: ";
document.getElementById("scoreText").textContent = "Your Score: " + score;
function updateUserScore() {
fetch("/leaderboard/update", {method: 'post', body: formData}
).then(response => response.json()
).then(responseData => {
if (responseData.hasOwnProperty('error')) {
alert(responseData.error);
} else {
}
});
}
}
if(x>900 || check()){
x=20;
document.getElementById("val").value = ''; //if inputed value get match then blank the input box.
}
},1000/fps)
}
function drawEverything(x,string ){ // draws text etc
canvasContext.fillStyle="rgba(0,0,200,0)"; // background colour
canvasContext.border="white"
canvasContext.fillRect(20,20,canvas.width,canvas.height);
drawString(x,string);
scoreBoard(score);
highScoreBoard(highscore);
}
function moveEverything(){
x+=4; // movement speed of the word
}
function drawString(x,string) {
canvasContext.font="30px Verdana";
canvasContext.fillStyle='gray';
canvasContext.fillText(string,x,280); // place of text appearing.
}
function Background(){ // sets background
this.x = 0, this.y = 0, this.w = bg.width, this.h = bg.height;
this.render = function(){
canvasContext.drawImage(bg, this.x--, 0);
if(this.x <= -499){
this.x = 0;
}
}
}
var background = new Background(); // actual background animation
function animate(){
background.render();
}
var animateInterval = setInterval(animate, 40);
function getWord(WordID) {
WordID = Math.floor(Math.random()*30) +1
difficultyWordID = WordID
if (WordID === null) {
} else
fetch("/words/single/" + WordID, {method: 'get'}
).then(response => response.json()
).then(responseData => {
if (responseData.hasOwnProperty('error')) {
alert(responseData.error);
} else {
string = responseData.Definition;
}
});
}
function check(WordID){
var userVal = document.getElementById("val").value;
if(userVal==string){
return true;
}
return false;
}
function scoreVal(){
if(check()){
fetch("/words/single/" + difficultyWordID, {method: 'get'}
).then(response => response.json()
).then(responseData => {
if (responseData.hasOwnProperty('error')) {
alert(responseData.error);
} else {
let difficultyScore = 1;
difficultyScore = responseData.Difficulty;
score=score + difficultyScore;
}
});
}
}
function highScoreVal(){
if(score>highscore){
highscore=score;
}
}
function scoreBoard(score){
scoreVal(WordID);
canvasContext.fillStyle = "White";
canvasContext.font = "40px hot_sauceitalic";
canvasContext.fillText("Your Score: ",50,60);
canvasContext.fillStyle = "White";
canvasContext.fillText(score, 250, 60);
}
function highScoreBoard(highscore){
highScoreVal();
canvasContext.fillStyle = "White";
canvasContext.fillText("Lives:",750,60);
canvasContext.fillStyle = "White";
canvasContext.font = "40px hot_sauceitalic";
canvasContext.fillText(lives, 850, 60);
}
I am unsure how to go about fixing this as I cant really work out the problem myself, I am assuming that it is to do with how it is drawing the background alongside the moving words.
EDIT - Tried using background-image and got this instead.
https://i.stack.imgur.com/UhNai.png

How to make a player not collide with a platform and certain conditions in Phaser 2 (CE)

I am coding a platformer, I make a collision between the platform and the player so that he can pass the platforms but the player does not pass through the platforms
Building the platform:
for (var i = 0; i < 35; i++) {
var type = i % 2 === 1 ? 'platform' : 'ice-platform';
var platform = this.platforms.create(x, y, type);
if (platform.key === 'ice-platform') {
platform.body.velocity.x = this.rnd.between(50, 100);
if (Math.random() > 0.5) {
platform.body.velocity.x *= -1;
}
}
wrapPlatform: function (platform) {
if (platform.key === 'ice-platform') {
if (platform.body.velocity.x < 0 && platform.x <= -160) {
platform.x = 640;
} else if (platform.body.velocity.x > 0 && platform.x >= 600) {
platform.x = -160;
}
}
},
Collision with a player:
setFriction: function (player, platform) {
if (platform.key === 'ice-platform') {
player.body.x -= platform.body.x - platform.body.prev.x;
}
},
Tip : use game.add.sprite(...) because if you use ...add.image... it will not work
var game = new Phaser.Game(800, 600, Phaser.AUTO, 'game', { preload: preload, create: create, update: update });
var ground, player;
var cursors;
function preload() {
this.load.baseURL = 'https://raw.githubusercontent.com/nazimboudeffa/assets/master/';
this.load.crossOrigin = 'anonymous';
this.load.image('ground', 'pics/platform.png');
this.load.image('dude', 'sprites/phaser-dude.png');
}
function create() {
game.physics.startSystem(Phaser.Physics.ARCADE);
ground = game.add.sprite(0, 200, 'ground');
game.physics.arcade.enable(ground);
ground.body.enable = true;
ground.body.immovable = true;
player = game.add.sprite(0, 300, 'dude');
game.physics.arcade.enable(player);
player.body.gravity.y = 300;
player.body.collideWorldBounds = true;
cursors = game.input.keyboard.createCursorKeys();
}
function update(){
if (player.y < ground.y){
game.physics.arcade.collide(player, ground)
}
if(cursors.up.isDown){
player.body.velocity.y = -240;
}
}
<script src="https://cdn.jsdelivr.net/npm/phaser-ce#2.13.1/build/phaser.js"></script>

Updating Sprites In Array With For Loop

I'm messing around with JavaScript game development and I have an issue with loading sprites from an array. It works fine updating this "mob" class individually but when I use a for-loop to update them the sprite trails and repeats itself.
Here is the code associated with the sprite loader and also the code for the sprite itself.
MobLoader
function mobloader(){
var self = this;
for (c = 0; c < 3; c++){
var t = new enemy(rInt(10, 400), rInt(10,400));
enemies.push(t);
}
self.updatemobs = function(){
for (l = 0; l < enemies.length; l++){
enemies[l].updatemob();
}
}
}
Enemy Class (the weeds)
function enemy(x, y){
var self = this;
self.x = x;
self.y = y;
self.name = "Jake";
self.enemyspr = new sprite("grasstest.png", self.x, self.y, 40, 40, 1, 1, 0, false);
self.updatemob = function(){
for (s = 0; s < spells.length; s++){
if (spells[s].cy >= self.enemyspr.y && spells[s].cy <= self.enemyspr.y + self.enemyspr.h && spells[s].cx <= self.enemyspr.x + self.enemyspr.w && spells[s].cx >= self.enemyspr.x && self.enemyspr.active == true ){
self.enemyspr.active = false;
spells[s].spellspr.active = false;
}
}
self.enemyspr.update();
}
}
Basic Sprite Class
function sprite(src, x, y, w, h, f, l, a, loaded){
var self = this;
self.src = src;
self.x = x;
self.y = y;
self.w = w;
self.h = h;
self.cf = 0;
self.f = f;
self.cl = 0;
self.l = l;
self.active = true;
self.a = a;
self.cfps = 0;
self.fps = 10;
self.loaded = loaded;
self.spr = new Image();
self.spr.onload = function(){self.loaded = true;}
self.spr.src = self.src;
self.update = function(){
if (self.active == true){
self.cfps += 1;
if (self.cfps > self.fps && self.a == 1){
self.cfps = 0;
self.cf += 1;
if (self.cf >= self.f){
self.cf = 0;
}
}
if (self.a == 3){
if (self.f > 9){
self.cl = Math.floor(self.f / 10);
self.cf = self.f - (Math.floor(self.f / 10) * 10);
}
if (self.f <=9){
self.cf = self.f;
self.cl = self.l;
}
}
ctx.drawImage(self.spr, self.w * self.cf, self.h * self.cl, self.w, self.h, self.x, self.y, self.w, self.h);
}
}
}
Base Class Which Clears the Canvas With Each Refresh
function gameupdate(){
ctx.fillStyle = bgcolor;
ctx.fillRect(0, 0, c.width, c.height);
updategame();
}
setInterval(gameupdate, 16);
You need to clear the canvas before you redraw the frame.
I agree with the answer above. Check with a console.log to see if it is actully running, and if that doesn't work replace bgcolor with "rgb"255,255,0" just for testing, because somthing might be wrong there. Only other thing it could be is that you are spawning an entity every time he walks/frame updates. I highly, highly doubt that though.

Drawing more than 1 to canvas wont work?

I am trying to draw enemy ships to the canvas that will come from the right at a random x being the height of the canvas and a random y past the right side + 1000.
This works fine however I am trying to make it automated and the code runs run it just does not work on screen, only 1 is drawn? Any more info that you need just ask, It's really frying my brain I went line by line for around 3 hours and can't see an issue.
Before I added this code and just called one manually: http://www.taffatech.com/DarkOrbit.html
After I added this code for automatic: (it kinda looks like its overlapping)
http://www.taffatech.com/test.html
Globals:
var spawnInterval;
var totalEnemies = 0; //leave as is
var enemies = []; //array of enemy objects
var spawnRate = 2000; //every 2 seconds
var spawnAmount = 3; //amount of enemies spawned
Then my init() calls a startLoop:
function startLoop()
{
isPlaying = true;
Loop();
startSpawningEnemies();
}
function stopLoop()
{
isPlaying = false;
stopSpawningEnemies();
}
function Loop()
{
if (isPlaying == true)
{
Player1.draw();
requestAnimFrame(Loop);
drawAllEnemies();
}
then they use these functions:
function spawnEnemy(n) //total enemies starts at 0 and every-time you add to array
{
for (var x = 0; x < n; x++)
{
enemies[totalEnemies] = new Enemy();
totalEnemies++;
}
}
function drawAllEnemies()
{
ClearEnemyCanvas();
for(var i = 0; i < enemies.length; i++)
{
enemies[1].draw();
}
}
function startSpawningEnemies()
{
stopSpawningEnemies();
spawnInterval = setInterval(function() {spawnEnemy(spawnAmount);}, spawnRate); //this calls spawnEnemy every spawnRate
/////////spawn 'spawnAmount' enemies every 2 seconds
}
function stopSpawningEnemies()
{
clearInterval(
spawnInterval);
}
which in turn calls the Enemy class:
function Enemy() //Object
{
//////Your ships values
this.EnemyHullMax = 1000;
this.EnemyHull = 1000;
this.EnemyShieldMax = 1000;
this.EnemyShield = 347;
this.SpaceCrystalReward = 2684;
this.EnemySpeed = 2; //should be around 6 pixels every-time draw is called by interval, directly linked to the fps global variable
////////////
////Pick Ship
this.type = "Hover";
this.srcX = EnemySrcXPicker(this.type);
this.srcY = EnemySrcYPicker(this.type);
this.enemyWidth = EnemyWidthPicker(this.type);
this.enemyHeight = EnemyHeightPicker(this.type);
this.drawX = EnemydrawXPicker(this.type);
this.drawY = EnemydrawYPicker(this.type);
////
}
Enemy.prototype.draw = function()
{
this.drawX -= this.EnemySpeed;
ctxEnemy.globalAlpha=1;
ctxEnemy.drawImage(spriteImage,this.srcX,this.srcY,this.enemyWidth,this.enemyHeight,this.drawX,this.drawY,this.enemyWidth,this.enemyHeight);
}
function EnemySrcXPicker(type)
{
if (type == "Hover")
{
return 906;
}
}
function EnemySrcYPicker(type)
{
if (type == "Hover")
{
return 616;
}
}
function EnemydrawXPicker(type)
{
if (type == "Hover")
{
return Math.floor(Math.random() * 1000) + canvasWidthEnemy;
}
}
function EnemydrawYPicker(type)
{
if (type== "Hover")
{
return Math.floor(Math.random() * (canvasHeightEnemy - 72));
}
}
function EnemyWidthPicker(type)
{
if (type == "Hover")
{
return 90;
}
}
function EnemyHeightPicker(type)
{
if (type == "Hover")
{
return 72;
}
}
for(var i = 0; i < enemies.length; i++)
{
enemies[1].draw();
}
should probably be
for(var i = 0; i < enemies.length; i++)
{
enemies[i].draw();
}
...or you'll draw the same enemy over and over.
In your drawAllEnemies function, shouldn't
enemies[1].draw();
be
enemies[i].draw();
?
When you loop the enemies array you should use the index i that you setup so that it doesn't continually draw the same element:
for(var i = 0; i < enemies.length; i++)
{
enemies[i].draw();
}

Categories

Resources