Let me try to explain what I have now, and what I am trying to add to it. Right now I have a canvas, 500x899 following a sprite(player), onto a background image(map) that's 5000x3750. Both are on the same sprite sheet. Right now if the arrow keys are pressed, the Player sprite moves in that direction along the Map while the canvas follows the player. - But what I would like is to have the left/right arrow keys rotate the player and the up key to move the player in that direction. Here's my code, it is a lot, but its organized:
// wrapper for "class" Rectangle
(function(){
function Rectangle(left, top, width, height){
this.left = left || 0;
this.top = top || 0;
this.right = (left + width) || 0;
this.bottom = (top + height) || 0;
}
Rectangle.prototype.set = function(left, top, width, height){
this.left = left;
this.top = top;
this.width = width || this.width;
this.height = height || this.height;
this.right = (this.left + this.width);
this.bottom = (this.top + this.height);
}
Rectangle.prototype.within = function(r) {
return (r.left <= this.left &&
r.right >= this.right &&
r.top <= this.top &&
r.bottom >= this.bottom);
}
Rectangle.prototype.overlaps = function(r) {
return (this.left < r.right &&
r.left < this.right &&
this.top < r.bottom &&
r.top < this.bottom);
}
// add "class" Rectangle to our Game object
Game.Rectangle = Rectangle;
})();
// wrapper for "class" Camera (avoid global objects)
(function(){
// possibles axis to move the camera
var AXIS = {
NONE: "none",
HORIZONTAL: "horizontal",
VERTICAL: "vertical",
BOTH: "both"
};
// Camera constructor
function Camera(xView, yView, canvasWidth, canvasHeight, worldWidth, worldHeight)
{
// position of camera (left-top coordinate)
this.xView = xView || 0;
this.yView = yView || 0;
// distance from followed object to border before camera starts move
this.xDeadZone = 0; // min distance to horizontal borders
this.yDeadZone = 0; // min distance to vertical borders
// viewport dimensions
this.wView = 800;
this.hView = 599;
// allow camera to move in vertical and horizontal axis
this.axis = AXIS.BOTH;
// object that should be followed
this.followed = null;
// rectangle that represents the viewport
this.viewportRect = new Game.Rectangle(this.xView, this.yView, this.wView, this.hView);
// rectangle that represents the world's boundary (room's boundary)
this.worldRect = new Game.Rectangle(this.xView, this.yView, this.wView, this.hView);
}
// gameObject needs to have "x" and "y" properties (as world(or room) position)
Camera.prototype.follow = function(gameObject, xDeadZone, yDeadZone)
{
this.followed = gameObject;
this.xDeadZone = xDeadZone;
this.yDeadZone = yDeadZone;
}
Camera.prototype.update = function()
{
// keep following the player (or other desired object)
if(this.followed != null)
{
if(this.axis == AXIS.HORIZONTAL || this.axis == AXIS.BOTH)
{
// moves camera on horizontal axis based on followed object position
if(this.followed.x - this.xView + this.xDeadZone > this.wView)
this.xView = this.followed.x - (this.wView - this.xDeadZone);
else if(this.followed.x - this.xDeadZone < this.xView)
this.xView = this.followed.x - this.xDeadZone;
}
if(this.axis == AXIS.VERTICAL || this.axis == AXIS.BOTH)
{
// moves camera on vertical axis based on followed object position
if(this.followed.y - this.yView + this.yDeadZone > this.hView)
this.yView = this.followed.y - (this.hView - this.yDeadZone);
else if(this.followed.y - this.yDeadZone < this.yView)
this.yView = this.followed.y - this.yDeadZone;
}
}
// update viewportRect
this.viewportRect.set(this.xView, this.yView);
// don't let camera leaves the world's boundary
if(!this.viewportRect.within(this.worldRect))
{
if(this.viewportRect.left < this.worldRect.left)
this.xView = this.worldRect.left;
if(this.viewportRect.top < this.worldRect.top)
this.yView = this.worldRect.top;
if(this.viewportRect.right > this.worldRect.right)
this.xView = this.worldRect.right - this.wView;
if(this.viewportRect.bottom > this.worldRect.bottom)
this.yView = this.worldRect.bottom - this.hView;
}
}
// add "class" Camera to our Game object
Game.Camera = Camera;
})();
// wrapper for "class" Player
(function(){
function Player(x, y){
// (x, y) = center of object
// ATTENTION:
// it represents the player position on the world(room), not the canvas position
this.x = x;
this.y = y;
// move speed in pixels per second
this.speed = 200;
// render properties
this.width = 85;
this.height = 80;
}
Player.prototype.update = function(step, worldWidth, worldHeight){
// parameter step is the time between frames ( in seconds )
// check controls and move the player accordingly
if(Game.controls.left)
this.x -= this.speed * step;
if(Game.controls.up)
this.y -= this.speed * step;
if(Game.controls.right)
this.x += this.speed * step;
if(Game.controls.down)
this.y += this.speed * step;
// don't let player leaves the world's boundary
if(this.x - this.width/2 < 0){
this.x = this.width/2;
}
if(this.y - this.height/2 < 0){
this.y = this.height/2;
}
if(this.x + this.width/2 > worldWidth){
this.x = worldWidth - this.width/2;
}
if(this.y + this.height/2 > worldHeight){
this.y = worldHeight - this.height/2;
}
}
Player.prototype.draw = function(context, xView, yView){
context.save();
// before draw we need to convert player world's position to canvas position
context.drawImage(imgSprite,1700,599, this.width, this.height,(this.x-this.width/2) - xView, (this.y-this.height/2) - yView, this.width, this.height);
context.restore();
}
// add "class" Player to our Game object
Game.Player = Player;
})();
// wrapper for "class" Map
(function(){
function Map(width, height){
// map dimensions
this.width = width;
this.height = height;
// map texture
this.image = null;
}
// generate an example of a large map
Map.prototype.generate = function(){
this.x = 0;
this.y = 0;
var ctx = document.createElement("canvas").getContext("2d");
ctx.canvas.width = this.width;
ctx.canvas.height = this.height;
ctx.drawImage(imgSprite,0,2250,this.width,this.height,this.x,this.y,this.width,this.height);
ctx.restore();
// store the generate map as this image texture
this.image = new Image();
this.image.src = ctx.canvas.toDataURL("image/png");
// clear context
ctx = null;
}
// draw the map adjusted to camera
Map.prototype.draw = function(context, xView, yView){
var sx, sy, dx, dy;
var sWidth, sHeight, dWidth, dHeight;
// offset point to crop the image
sx = xView;
sy = yView;
// dimensions of cropped image
sWidth = context.canvas.width;
sHeight = context.canvas.height;
// if cropped image is smaller than canvas we need to change the source dimensions
if(this.image.width - sx < sWidth){
sWidth = this.image.width - sx;
}
if(this.image.height - sy < sHeight){
sHeight = this.image.height - sy;
}
// location on canvas to draw the croped image
dx = 0;
dy = 0;
// match destination with source to not scale the image
dWidth = sWidth;
dHeight = sHeight;
context.drawImage(this.image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);
}
// add "class" Map to our Game object
Game.Map = Map;
})();
// Game Script
(function(){
// prepaire our game canvas
var canvas = document.getElementById("gameCanvas");
var context = canvas.getContext("2d");
// game settings:
var FPS = 30;
var INTERVAL = 1000/FPS; // milliseconds
var STEP = INTERVAL/1000 // seconds
// setup an object that represents the room
var room = {
width: 5000,
height: 3750,
map: new Game.Map(5000, 3750)
};
// generate a large image texture for the room
room.map.generate();
// setup player
var player = new Game.Player(85, 80);
// setup the magic camera !!!
var camera = new Game.Camera(0, 0, 800, 599, room.width, room.height);
camera.follow(player, 800/2, 599/2);
// Game update function
var update = function(){
player.update(STEP, room.width, room.height);
camera.update();
}
// Game draw function
var draw = function(){
// clear the entire canvas
context.clearRect(0, 0, 800, 599);
// redraw all objects
room.map.draw(context, camera.xView, camera.yView);
player.draw(context, camera.xView, camera.yView);
}
// Game Loop
var gameLoop = function(){
update();
draw();
}
// <-- configure play/pause capabilities:
// I'll use setInterval instead of requestAnimationFrame for compatibility reason,
// but it's easy to change that.
var runningId = -1;
Game.play = function(){
if(runningId == -1){
runningId = setInterval(function(){
gameLoop();
}, INTERVAL);
console.log("play");
}
}
Game.togglePause = function(){
if(runningId == -1){
Game.play();
}
else
{
clearInterval(runningId);
runningId = -1;
console.log("paused");
}
}
})();
// <-- configure Game controls:
Game.controls = {
left: false,
up: false,
right: false,
down: false,
};
window.addEventListener("keydown", function(e){
switch(e.keyCode)
{
case 37: // left arrow
Game.controls.left = true;
break;
case 38: // up arrow
Game.controls.up = true;
break;
case 39: // right arrow
Game.controls.right = true;
break;
case 40: // down arrow
Game.controls.down = true;
break;
}
}, false);
window.addEventListener("keyup", function(e){
switch(e.keyCode)
{
case 37: // left arrow
Game.controls.left = false;
break;
case 38: // up arrow
Game.controls.up = false;
break;
case 39: // right arrow
Game.controls.right = false;
break;
case 40: // down arrow
Game.controls.down = false;
break;
case 80: // key P pauses the game
Game.togglePause();
break;
}
}, false);
// start the game when page is loaded
window.onload = function(){
Game.play();
}
Again this works for the canvas to follow the player and all, but now I'm trying to rotate the player sprite using the arrow keys. I'v used google and tried some codes similar too :
var thrust = 0;
var rotation = 0;
ctxPlayer.translate(this.width/2, this.height/2);
ctxPlayer.rotate(this.angle);
ctxPlayer.translate(this.x,this.y);
if(Game.controls.left)
this.angle =-3
(Sorry i dont have exactly what I have tried regarding the rotation, as I've deleted them every time it didn't work). Using codes similiar to this the only rotation I have gotten is the player rotating in a giant circle around a coordinate. (Not actually rotating in one spot and not with the push of a key)
Any help or advice is really appreciated.
Change the order of operations. Rotate the sprite first, then move it. You will want the center of your sprite to be at 0,0 (top left) in order to get the effect your looking for. The following code assumes your already starting at 0,0:
ctxPlayer.save();
ctxPlayer.translate(this.x,this.y);
ctxPlayer.rotate(this.angle);
ctxPlayer.translate(-this.width/2,-this.height/2); // before we draw the sprite lets set the anchor point to its center.
ctxPlater.restore();
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.