const canvas = document.querySelector('#snake');
const ctx = canvas.getContext('2d');
//create canvas unit
const box = 32;
//load image files
const ground = new Image();
ground.src = 'img/ground.png';
const food = new Image();
food.src = 'img/food.png';
//load audio files
let dead = new Audio();
let eat = new Audio();
let up = new Audio();
let down = new Audio();
let left = new Audio();
let right = new Audio();
dead.src = 'audio/dead.mp3';
eat.src = 'audio/eat.mp3';
left.src = 'audio/left.mp3';
up.src = 'audio/up.mp3';
down.src = 'audio/down.mp3';
right.src = 'audio/right.mp3';
//create snake
let snake = [];
//draw canvas
ctx.drawImage(ground, 0, 0)
canvas {
display: block;
margin: 0 auto;
}
<canvas id="snake" width="608" height="608"></canvas>
I'm following a tutorial on YouTube on how to make a snake game with javascript. I copied his code and commented it out. Now I'm reconstructing it piece by piece to see how it works, but not step by step.
For instance once i created the global variables i wanted to draw the background image to the canvas just to look at it ctx.drawImage(ground, 0, 0); this by itself doesn't work. Watching him do it in the video he creates a draw function, puts that code in it, then sets the function to run at an interval of 100ms.
function draw() {
ctx.drawImage(ground, 0, 0);
}
let game = setInterval(draw, 100);
Now it works?? what's happening?
here's his github https://github.com/CodeExplainedRepo/Snake-JavaScript
I'm know i'm late. I was asking myself the same question after seeing that tutorial...
But still, you can pass this problem by simply adding the property background-image :
canvas id="snakeCanvas" width="608" height="608" style="background-image: url(img/ground.png)"
Related
I started a simple project in javascript a few days ago and found this issue. Every time I reload my google-page i get an empty canvas. I have already tried to take out the drawImage() function out of class and it worked. But what if I need to use that function as a class method? (Also I've already tried passing the canvas as an argument of the draw method but it doesn't work)
So this is working but I don't need it
const canvas = document.getElementById('main_canvas')
const ctx = canvas.getContext('2d')
var img = new Image()
img.src = 'some source'
ctx.drawImage(img,10,10)
And this isn't working but supposed to
const canvas = document.getElementById('main_canvas')
const ctx = canvas.getContext('2d')
class Person
{
constructor(name){
this.name = name
this.img = new Image()
this.img.src = 'some source'
}
draw(){
ctx.drawImage(this.img,10,10)
}
}
var peter = new Person('Peter Griffin')
peter.draw()
The reason is simple. Your image is not loaded when you want to draw it.
You have to wait until the image is loaded before drawing it in the canvas.
const canvas = document.getElementById('main_canvas')
const ctx = canvas.getContext('2d')
class Person
{
constructor(name){
this.name = name;
this.img = new Image()
this.img.src = 'monimage.jpg'
}
on_image_loaded(f) {
this.img.onload = f;
}
draw(){
ctx.drawImage(this.img,10,10)
}
}
var peter = new Person('Peter Griffin')
peter.on_image_loaded(function() {
peter.draw();
});
I was trying to create a sample pixi application. Where I had an image, when user clicks on the image, it should move its position.
var canvasWidth = window.innerWidth;
var canvasHight = window.innerHeight
var renderer = PIXI.autoDetectRenderer(canvasWidth, canvasHight);
document.body.appendChild(renderer.view);
var stage = new PIXI.Container();
PIXI.loader
.add('images/sample.png')
.add('images/background.jpg')
.load(setup);
function setup() {
var backGround = new PIXI.Sprite(
PIXI.loader.resources["images/background.jpg"].texture);
var steve = new PIXI.Sprite(
PIXI.loader.resources["images/sample.png"].texture);
backGround.hieght = canvasHight;
backGround.width = canvasWidth;
setPropertiesToSteve(steve);
stage.addChild(backGround);
stage.addChild(steve);
renderer.render(stage);
}
// Function just to set properties for steve
function setPropertiesToSteve(steve) {
steve.interactive = true;
steve.position.x = canvasWidth/2;
steve.position.x = canvasWidth/4;
steve.on('pointerdown',function(){
steve.position.x = steve.position.x + 10;
});
}
But when I click on the object nothing happening. I am very much new to pixijs.SO don't know how to handle this.
You need to render the stage again :)
Take a look at the official Pixi examples https://pixijs.github.io/examples/
They use the PIXI.Application class which sets up common things like a ticker that automatically re renders your stage
I made a scene in Blender that I exported into a .babylon, and now I am importing it into the game. The map is 351KB, and I am loading it into the game like this:
var BABYLON;
var canvas = document.getElementById('gamecanvas');
var engine = new BABYLON.Engine(canvas, true);
var scene = new BABYLON.Scene(engine);
var light = new BABYLON.PointLight('light', new BABYLON.Vector3(0,0,10), scene);
var player = new BABYLON.FreeCamera('player', new BABYLON.Vector3(1,1,1), scene); //IMPORTANT LINE
var player_height = 2;
var player_speed = 1;
var player_inertia = 0.9;
var mouse_position = new BABYLON.Vector2(mouse_position.x, mouse_position.y);
function INIT_GAME(){
engine.runRenderLoop(function(){ //IMPORTANT LINE
scene.render();
});
canvas.height = window.innerHeight;
canvas.width = window.innerWidth;
canvas.requestPointerLock = canvas.requestPointerLock || canvas.mozRequestPointerLock;
canvas.requestPointerLock();
scene.enablePhysics(); //IMPORTANT LINE
scene.setGravity(new BABYLON.Vector3(0, -10, 0)); //IMPORTANT LINE
player.attachControl(canvas, true); //IMPORTANT LINE
player.ellipsoid = new BABYLON.Vector3(1, player_height, 1);
player.checkCollisions = true;
player.applyGravity = true;
player.keysUp = [87];
player.keysDown = [83];
player.keysLeft = [65];
player.keysRight = [68];
player.inertia = player_inertia;
player.speed = player_speed;
window.addEventListener('resize', function(){
engine.resize();
});
BABYLON.SceneLoader.Load('Scenes', 'zombie_map.babylon', engine); //IMPORTANT LINE
}
I've attempted to narrow everything down to what you should need to look at, but I left it all there just in case there was something I missed. (INIT_GAME is loaded on page load). My problem is, I think the scene is loading, but it just gives me a strange loading icon, which I presume is just Babylon trying to load in the scene I passed it. My questions are:
Am I loading everything in properly?
What is the proper format to import a .babylon scene?
Is the size of the map too big for the browser, and if so, how can I compress it?
I can provide a link to the site if you need to see the results head-on. Let me know, thanks!
I think the solution is very simple.
Add a slash after your rootURL.
So replace
BABYLON.SceneLoader.Load('Scenes', 'zombie_map.babylon', engine); //IMPORTANT LINE
with
BABYLON.SceneLoader.Load('Scenes/', 'zombie_map.babylon', engine); //IMPORTANT LINE
Try this and let me know how it goes.
The Problem
I am finding it rather difficult to get my head around this, I am attempting to move an image using the mouse along the X axis only. I am finding it hard to even move the image at all and the many tutorials I have looked at arnt really helping me. Here is what I am trying to say:
As you can see by my beautiful image above I only want to image to move left and right at the bottom of the page.
The Code and the Question
Here is my first attempt, when I try this all the images loaded on the canvas no longer appear making it very hard for me to understand why it isnt working.
<script type="text/javascript">
//Referencing the canvas
var canvas = document.getElementById("myCanvas");
var context = canvas.getContext("2d");
var width = canvas.getAttribute('width');
var height = canvas.getAttribute('height');
//Images
var bggameImage = new Image();
var playerImage = new Image();
var enemyImage = new Image();
var projectileImage = new Image();
var livesImage = new Image();
//Canvas dimensions
var width = 480;
var height = 320;
//Loading in the backgroundImage
bggameImage.src = "Images/bggameImage.png";
bggameImage.onload = function(){
context.drawImage(bggameImage, 0, 0);
}
//Loading in the playerImage
playerImage.src = "Images/playerImage.png";
playerImage.onload = function(){
context.drawImage(playerImage, 165, 240);
}
//Loading in the projectileImage
projectileImage.src = "Images/projectileImage.png";
projectileImage.onload = function(){
context.drawImage(projectileImage, 65, 240);
}
var playerImage = {
x:176,
y:74,
}
function init() {
playerImage.src = "Images/playerImage.png";
//Moving player
myCanvas.addEventListener("mousemove", function (e) {
var bounding_box = myCanvas.getBoundingClientRect();
playerImage = (e.clientX - bounding_box.left) * (myCanvas.width / bounding_box.width) - playerImage.width / 2;
playerImage = (e.clientY - bounding_box.top) * (myCanvas.height / bounding_box.height) - playerImage.height / 2;
}
)
</script>
The whole "function init()" part is what I have just tried but I thought I would include this anyway, I understand that I am loading in the playerImage twice.
You're using the same variable name twice (playerImage), so your image is being overwritten. You're using it for the image and also to store the position. Change the playerImage that's storing x and y to be playerPosition or something like that. Update that variable on your mouse event and then render the image according to that variable's values.
Ultimately, you're going to have to look at a game loop using setTimeout or requestAnimationFrame. So, this will become crucial at that stage. And yes, you shouldn't be loading the player image twice either. Do all of that at the start and only start your game when all your assets have successfully loaded.
For instance...
var playerImage;
var alienImage;
var bulletImage;
var assetCount = 0;
function loadAssets() {
playerImage = new Image();
playerImage.onload = checkAssetsLoaded;
playerImage.src = "assets/images/Brush01.png";
alienImage = new Image();
alienImage.onload = checkAssetsLoaded;
alienImage.src = "assets/images/Brush02.png";
bulletImage = new Image();
bulletImage.onload = checkAssetsLoaded;
bulletImage.src = "assets/images/Brush03.png";
}
function checkAssetsLoaded(event) {
assetCount++;
console.log("An asset has loaded!: " + assetCount);
if (assetCount == 3) {
startGame();
}
}
function startGame() {
// Start your game initialization logic here.
console.log("Game starting!");
}
I am making a mahjong game in js and I have a problem loading images on canvas
canvas
// Create the canvas
var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
canvas.width = 512;
canvas.height = 512;
//draw canvas
document.body.appendChild(canvas);
Arrays
//Array with Tiles & set length to 144 which are the requested tiles
var tiles = new Array(2);//will be 144
//2D map array for showing the images coordinates
var map = [[69,50],[100,150]];//will be 144 coordinates
my function update()
function update(){
for(var i=0;i<tiles.length;i++){
//make the tile object
tiles[i] = new Object();
tiles[i].id = i ;
tiles[i].selected = false;
//set the coordinates from map Array
tiles[i].x=map[i][0];
tiles[i].y=map[i][1];
//tiles[i].ready=false;
//These are for the image location works fine
//convert i to String
var sourceNumber = i.toString();
//add .png to String
var source = sourceNumber.concat(png);
//add /image
var source = dest.concat(source);
tiles[i].img = new Image();
tiles[i].img.onload = function(){
//tiles[i].ready=true;
ctx.drawImage(tiles[i].img,tiles[i].x,tiles[i].y,xdimension,ydimension);
};
tiles[i].img.src = source ;
}
}
I runned it on each of my browser it won't load images , I debugged on chrome and it says on ctx.drawImage(...); -> Uncaught TypeError: Cannot read property 'img' of undefined(repeated many times), So I tried the tiles[I].ready and after load images but still has that error.Any suggestions on how should I implement the loading of the tile images
The first time ctx.drawImage is called, the value for i is 2. The problem is that the for-loop (for(var i=0;i<tiles.length;i++)) has finished executing before any of the images have loaded. Consequently, the value of i at the time the onload function is called is the value at which the loop ceased being run. The easiest way around this is to save the index (i) into the img element itself, so that you can retrieve it in the onload handler.
Here's a simple adaption of your code that seems to work just fine.
The important changes are:
tiles[i].img.iVal = i;
and the body of the onload handler.
I also:
(a) added an array to hold hard-coded image names for convenience, rather than dynamically creating them (I'd have had to name some images into the format that the code computes)
(b) removed the xdimension and ydimension vars from the drawImage call since I dont know what they are.
(c) changed .concat(png) to .concat(".png") since it was easier than declaring a variable called png that holds the string .png
Anyway, here's the sample-code I used:
<!DOCTYPE html>
<html>
<head>
<script>
window.addEventListener('load', onDocLoaded, false);
var canvas, ctx, tiles, map;
function onDocLoaded()
{
canvas = newEl('canvas');
ctx = canvas.getContext('2d');
canvas.width = canvas.height = 512;
document.body.appendChild(canvas);
tiles = new Array(2);
map = [[69,50],[100,150]];
update();
}
var imgFileNames = ["img/girl.png", "img/redbaron.png"];
function update()
{
for(var i=0;i<tiles.length;i++)
{
//make the tile object
tiles[i] = new Object();
tiles[i].id = i ;
tiles[i].selected = false;
//set the coordinates from map Array
tiles[i].x=map[i][0];
tiles[i].y=map[i][1];
//tiles[i].ready=false;
//These are for the image location works fine
//convert i to String
// var sourceNumber = i.toString();
//add .png to String
// var source = sourceNumber.concat(".png");
//add /image
// var source = dest.concat(source);
tiles[i].img = new Image();
tiles[i].img.iVal = i;
tiles[i].img.onload =
function()
{
var curI = this.iVal;
ctx.drawImage(tiles[curI].img,tiles[curI].x,tiles[curI].y);
// ctx.drawImage(this,tiles[curI].x,tiles[curI].y); //equiv to above line
};
tiles[i].img.src = imgFileNames[i];
}
}
</script>
<style>
canvas
{
border: solid 1px red;
}
</style>
</head>
<body>
</body>
</html>