Reputation: 57
I wanted to build a little back and forth shooter game in Javascript as my final class project in digital art. However, the code I have written starts to run very slowly after only a few seconds. At first I was using setInterval(), but then switched over to requestAnimationFrame() to try and improve performance. This didn't work. Here is the code:
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d")
var youtube = new Image(); // Create new img element
var bullet = new Image();
var background = new Image();
var spaceship = new Image();
var url = new Image ();
var moveh = 150
var shipx = 150
var right = true
var rightPressed = false
var leftPressed = false
var spacePressed = false
var bulletUp = 280
var shot = false
var explosion = false
document.addEventListener("keydown", keyDownHandler, false);
document.addEventListener("keyup", keyUpHandler, false);
function keyDownHandler(e) {
if(e.keyCode == 39) {
rightPressed = true;
}else if(e.keyCode == 37) {
leftPressed = true;
}else if (e.keyCode == 32){
spacePressed = true
}
}
function keyUpHandler(e) {
if(e.keyCode == 39) {
rightPressed = false;
}
else if(e.keyCode == 37) {
leftPressed = false;
}
else if (e.keyCode == 32){
spacePressed = false;
}
}
function moveship(){
drawship()
canvas.width = canvas.width
if (rightPressed && shipx < 380){
shipx += 7
}
else if (leftPressed && shipx > 3){
shipx -= 7
}
}
function drawyoutube(){
youtube.addEventListener("load", function() {
ctx.drawImage(youtube, moveh,10);
}, false);
youtube.src = 'YouTube.png'; // Set source path
}
function drawbackground(){
background.addEventListener("load", function(){
ctx.drawImage(background, 0,0);
}, false);
background.src = "paper.jpg"
}
function drawship(){
spaceship.addEventListener("load", function(){
ctx.drawImage(spaceship, shipx, 250);
}, false);
spaceship.src = "SpaceShip.png";
}
function MoveYoutube(){
drawyoutube()
if (right == true){
moveh += 8
if (moveh > 380){
right = false
}
}
else if(right == false){
moveh -= 10
}if (moveh < 3){
right = true
}
}
function drawbullet(){
if (shot == true){
bullet.addEventListener("load", function(){
ctx.drawImage(bullet, shipx + 40, bulletUp);
}, false);
bullet.src = "bullet.png";
}
}
function shoot(){
if (spacePressed){
shot = true
}
else if (shot == true){
drawbullet()
bulletUp -= 10
}if (bulletUp == -20){
shot = false
bulletUp = 260
}else if(bulletUp == 10){
explosion == true
write()
}
}
}
function write(){
url.addEventListener("load", function(){
ctx.drawImage(background, 150,35);
}, false);
url.src = "url.png"
}
function draw(){
drawbackground()
moveship()
shoot()
MoveYoutube()
requestAnimationFrame(draw)
}
My gut is saying that it has to do with how I'm loading the images, but I don't know.
Upvotes: 0
Views: 912
Reputation: 416
As stated in the comment by Alexander O'Mara, you are trying to reload images every time you draw them.
Before you start the game logic, you need a step where you load all your image assets. Something like this:
var imageSrcs = ['YouTube.png', 'bullet.png', 'paper.jpg', 'SpaceShip.png', 'url.png'];
var images = [youtube, bullet, background, spaceship, url];
var loadCount = 0; // keep a count of images that have loaded so far
function loadImages() {
for(var i = 0; i<images.length; i++) {
loadImage(images[i], imageSrcs[i]);
}
}
function loadImage(img, src) {
img.addEventListener('load', imageLoaded);
img.src = src;
}
function imageLoaded() {
loadCount++;
if(loadCount === images.length) {
startGame();
}
}
You can then start the rendering and update loop from startGame knowing that all your images have already loaded. After that point you can be confident ctx.drawImage(spaceship, 0, 0)
should draw the image to canvas and you don't have to wrap it in a load event handler.
Upvotes: 1