I'm currently trying to code a simple game for class. Right now I want my rectangle to stay within the bounds of my canvas when i move it by using a bounce function, but it doesn't seem to be working and I cant figure out why. I have tried implementing my bounce function and calling it at the top. When I move my rectangle it goes past the bounds of the canvas without staying inside and "bouncing" off the border.
var canvas;
var ctx;
var w = 1000;
var h = 700;
var o1 = {
x: 100,
y: h/2,
w: 100,
h: 100,
c: 0,
a: 100,
angle: 0, //changes angle that shape sits at
distance: 10
}
document.onkeydown = function(e){keypress(e, o1)}
setUpCanvas();
// circle (o1);
animationLoop();
function animationLoop(){
//clear
clear();
//draw
rect(o1);
//update
bounce(o1)
requestAnimationFrame(animationLoop)
}
function bounce(o){
if(o.x o.w/2 > w || o.x-o.w/2 < 0){ //makes shape bounce from edge instead of middle. collision detection
o.changeX *= -1; //same as o.changeX = o.changeX = -1;
}
if(o.y o.h/2 > h || o.y-o.h/2 <0){
o.changeY *= -1;
}
}
function updateData(o){
o.x = o.changeX;
o.y = o.changeY;
}
function keypress(e,o){
if (e.key == "ArrowUp"){
o.angle = 270;
o.distance= 80;
forward(o);
}
if (e.key == "ArrowDown"){
o.angle = 90;
o.distance= 20;
forward(o);
}
}
function forward(o){ //makes shape able to move
var cx;
var cy;
cx = o.distance*Math.cos(o.angle);
cy = o.distance*Math.sin(o.angle)
o.y = cy;
}
function rect(o){
var bufferx = o.x;
var buffery = o.y
o.x = o.x - o.w/2;
o.y = o.y- o.h/2;
ctx.beginPath(); //this is very important when we are changing certain ctx properties
ctx.moveTo(o.x,o.y);
ctx.lineTo(o.x o.w,o.y);
ctx.lineTo(o.x o.w,o.y o.h);
ctx.lineTo(o.x, o.y o.h);
ctx.lineTo(o.x,o.y);
ctx.fillStyle = "hsla(" String (o.c) ",100%,50%," o.a ")";
ctx.fill();
o.x = bufferx; //o.x = o.x o.w/2;
o.y = buffery;//o.y = o.y o.h/2;
}
function clear(){
ctx.clearRect(0, 0, w, h);
}
function randn(range){
var r = Math.random()*range-(range/2);
return r
}
function rand(range){
var r = Math.random()*range
return r
}
function setUpCanvas(){
canvas = document.querySelector("#myCanvas");
canvas.width = w;
canvas.height = h;
// canvas.style.width = "1000px";
// canvas.style.height = "700px";
canvas.style.border = "10px solid black";
ctx = canvas.getContext("2d");
}
console.log("Final Assignment")
CodePudding user response:
You only need to setup changeX
and changeY
values in o1
, since they are not initialized to work with updateData
:
changeX: initialX,
changeY: initialY,
var canvas;
var ctx;
var w = 1000;
var h = 700;
var o1 = {
x: 100,
y: h/2,
w: 100,
h: 100,
c: 0,
a: 100,
angle: 0, //changes angle that shape sits at
distance: 10,
changeX: 5, // initialize with x vel
changeY: 4, // initialize with y vel
}
document.onkeydown = function(e){keypress(e, o1)}
setUpCanvas();
// circle (o1);
animationLoop();
function animationLoop(){
//clear
clear();
//draw
rect(o1);
//update
bounce(o1)
updateData(o1)
requestAnimationFrame(animationLoop)
}
function bounce(o){
if(o.x o.w/2 > w || o.x-o.w/2 < 0){ //makes shape bounce from edge instead of middle. collision detection
o.changeX *= -1; //same as o.changeX = o.changeX = -1;
}
if(o.y o.h/2 > h || o.y-o.h/2 <0){
o.changeY *= -1;
}
}
function updateData(o){
o.x = o.changeX;
o.y = o.changeY;
}
function keypress(e,o){
if (e.key == "ArrowUp"){
o.angle = 270;
o.distance= 80;
forward(o);
}
if (e.key == "ArrowDown"){
o.angle = 90;
o.distance= 20;
forward(o);
}
}
function forward(o){ //makes shape able to move
var cx;
var cy;
cx = o.distance*Math.cos(o.angle);
cy = o.distance*Math.sin(o.angle)
o.y = cy;
}
function rect(o){
var bufferx = o.x;
var buffery = o.y
o.x = o.x - o.w/2;
o.y = o.y- o.h/2;
ctx.beginPath(); //this is very important when we are changing certain ctx properties
ctx.moveTo(o.x,o.y);
ctx.lineTo(o.x o.w,o.y);
ctx.lineTo(o.x o.w,o.y o.h);
ctx.lineTo(o.x, o.y o.h);
ctx.lineTo(o.x,o.y);
ctx.fillStyle = "hsla(" String (o.c) ",100%,50%," o.a ")";
ctx.fill();
o.x = bufferx; //o.x = o.x o.w/2;
o.y = buffery;//o.y = o.y o.h/2;
}
function clear(){
ctx.clearRect(0, 0, w, h);
}
function randn(range){
var r = Math.random()*range-(range/2);
return r
}
function rand(range){
var r = Math.random()*range
return r
}
function setUpCanvas(){
canvas = document.querySelector("#myCanvas");
canvas.width = w;
canvas.height = h;
// canvas.style.width = "1000px";
// canvas.style.height = "700px";
canvas.style.border = "10px solid black";
ctx = canvas.getContext("2d");
}
console.log("Final Assignment")
<canvas id="myCanvas" ></canvas>
CodePudding user response:
In your code: o.changeX
and o.changeY
never do anything. So, it doesn't matter that bounce()
changes them.
But I can't suggest any easy fix. The biggest challenge here is that you're using angles. Was that required by the assignment? Game movement is super easy with vectors, but all geometry problems are extremely difficult to solve when using angles.
(I've written 3D game engines and a VR sculpting app, and never used a single angle or sin / cos anywhere at all, including for rotation matrices. I promise, angles a very bad idea.)
Edit:
Well, anyway, here's the simple and easy fix: Just stop using angles.
Only your keypress function changes:
//If you want the arrow key to change the direction your square is moving:
function keypress(e,o){
if (e.key == "ArrowUp"){
o.changeY = -1;
}
if (e.key == "ArrowDown"){
o.changeY = 1;
}
}
//If you want the arrow key to move your square, but not change the direction it was moving:
function keypress(e,o){
if (e.key == "ArrowUp"){
o.y -= 80;
//This value is huge. Do you really want to move your square 80 pixels? It's going to shoot off the screen in a flash. I would set this to 2.
}
if (e.key == "ArrowDown"){
o.y = 20;
}
}