I have this function:
for (var i in chars) {
chars[i].walk();
for (var j in chars) {
if (i != j) {
collision(chars[i], chars[j]);
action(chars[i], chars[j]);
}
}
}
Does it work unexpectedly when I first call, only when I call it a second time so it works? (does not work if I call her and then another and then call her again).
chars
is an array that holds objects of class Character
.
collision
works correctly and I tried to remove it and did not change anything.
Function walk
:
walk () {
if (!this.acting && this.walking) {
switch (this.walking) {
case "left":
this.animate(9, 9);
this.posX -= this.speed;
break;
case "right":
this.animate(11, 9);
this.posX += this.speed;
break;
case "up":
this.animate(8, 9);
this.posY -= this.speed;
break;
case "down":
this.animate(10, 9);
this.posY += this.speed;
break;
}
}
}
The complete files are these:
index.html
: <!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Undivine</title>
<link href="css/style.css" rel="stylesheet">
</head>
<body>
<div>
<canvas height="600" id="canvas" width="800"></canvas>
</div>
<script src="js/load.js" onload="loadJS('js/message', 'js/character', 'js/collision', 'js/script')"></script>
</body>
</html>
css/styles.css
: @import "https://fonts.googleapis.com/css?family=Alfa+Slab+One";
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
text-align: center;
}
#canvas {
background-color: #f00;
cursor: pointer;
margin-top: 10px;
}
js/character.js
: class Character {
constructor (img, posX, posY, visible) {
//propriedades
this.acting = null;
this.height = 64;
this.img = img;
this.posX = posX;
this.posY = posY;
this.speed = 3;
this.srcX = 0;
this.srcY = 10;
this.step = 0;
this.visible = visible;
this.walking = null;
this.width = 64;
}
//metodos
action () {
if (this.acting) {
switch (this.acting) {
case "spellcast":
var cols = 7;
var srcY = 0 + this.srcY % 4;
break;
case "thrust":
var cols = 8;
var srcY = 4 + this.srcY % 4;
break;
case "slash":
var cols = 6;
var srcY = 12 + this.srcY % 4;
break;
case "shoot":
var cols = 13;
var srcY = 16 + this.srcY % 4;
break;
case "hurt":
var cols = 6;
var srcY = 20;
break;
}
if (this.animate(srcY, cols)) {
var acting = this.acting;
this.acting = null;
this.step = 0;
if (acting != "hurt") {
this.srcX = 0;
}
return acting;
}
}
}
animate (srcY, cols) {
if (this.srcY == srcY) {
this.srcX = Math.floor(this.step / 5) % cols;
this.step++;
return this.step == cols * 5 - 1;
} else {
this.srcY = srcY;
this.step = 0;
}
}
bottomEdge () {
return this.posY + this.height;
}
centerX () {
return this.posX + this.width / 2;
}
centerY () {
return this.posY + this.height / 2;
}
cursor (e) {
return e.offsetX >= this.posX && e.offsetX < this.rightEdge() && e.offsetY >= this.posY && e.offsetY < this.bottomEdge()?true:false;
}
direction () {
switch (this.srcY % 4) {
case 0:
return "up";
break;
case 1:
return "left";
break;
case 2:
return "down";
break;
case 3:
return "right";
break;
}
}
draw (cnv, ctx) {
if (this.visible) {
switch (this.posX) {
case "center":
this.posX = (cnv.width - this.width) / 2;
break;
case "left":
this.posX = 0;
break;
case "right":
this.posX = cnv.width - this.width;
break;
}
switch (this.posY) {
case "middle":
this.posY = (cnv.height - this.height) / 2;
break;
case "top":
this.posY = 0;
break;
case "bottom":
this.posY = cnv.height - this.height;
break;
}
ctx.drawImage(this.img, this.srcX * this.width, this.srcY * this.height, this.width, this.height, this.posX, this.posY, this.width, this.height);
}
}
halfHeight () {
return this.height / 2;
}
halfWidth () {
return this.width / 2;
}
rightEdge () {
return this.posX + this.width;
}
stop (direction) {
if (this.walking == direction) {
this.walking = null;
}
}
walk () {
if (!this.acting && this.walking) {
switch (this.walking) {
case "left":
this.animate(9, 9);
this.posX -= this.speed;
break;
case "right":
this.animate(11, 9);
this.posX += this.speed;
break;
case "up":
this.animate(8, 9);
this.posY -= this.speed;
break;
case "down":
this.animate(10, 9);
this.posY += this.speed;
break;
}
}
}
}
js/collision.js
: function action (a, b) {
switch (a.action()) {
case "shoot":
shoot(a, b);
break;
case "thrust":
case "slash":
attack(a, b);
break;
}
}
function collision (a, b) {
var x = Math.abs(a.centerX() - b.centerX());
var y = Math.abs(a.centerY() - b.centerY());
var width = a.halfWidth() + b.halfWidth();
var height = a.halfHeight() + b.halfHeight();
if (x < width && y < height && b.visible) {
switch (a.direction()) {
case "up":
a.posY += height - y;
break;
case "left":
a.posX += width - x;
break;
case "down":
a.posY -= height - y;
break;
case "right":
a.posX -= width - x;
break;
}
}
}
function shoot (a, b) {
switch (a.direction()) {
case "up":
if (a.centerX() > b.posX && a.centerX() < b.rightEdge() && a.posY > b.posY) {
b.visible = false;
}
break;
case "left":
if (a.centerY() > b.posY && a.centerY() < b.bottomEdge() && a.posX > b.posX) {
b.visible = false;
}
break;
case "down":
if (a.centerX() > b.posX && a.centerX() < b.rightEdge() && a.posY < b.posY) {
b.visible = false;
}
break;
case "right":
if (a.centerY() > b.posY && a.centerY() < b.bottomEdge() && a.posX < b.posX) {
b.visible = false;
}
break;
}
}
function attack (c, d) {
var x = Math.abs(c.centerX() - d.centerX());
alert(x);
var y = Math.abs(c.centerY() - d.centerY());
var width = c.halfWidth() + d.halfWidth();
var height = c.halfHeight() + d.halfHeight();
switch (c.direction()) {
case "up":
if (x <= width && y <= height && c.posY > d.posY) {
d.visible = false;
}
break;
case "left":
if (x <= width && y <= height && c.posX > d.posX) {
d.visible = false;
}
break;
case "down":
if (x <= width && y <= height && c.posY < d.posY) {
d.visible = false;
}
break;
case "right":
if (x <= width && y <= height && c.posX < d.posX) {
d.visible = false;
}
break;
}
}
js/load.js
: //carrega javascript
function loadJS () {
for (var i in arguments) {
document.write("<script src='" + arguments[i] + ".js'></script>");
}
}
//carrega imagens
function loadImgs () {
var imgs = new Object();
for (var i in arguments) {
var start = arguments[i].lastIndexOf("/") + 1;
var end = arguments[i].indexOf(".");
var name = arguments[i].substring(start, end);
imgs[name] = new Image();
imgs[name].src = arguments[i];
}
return imgs;
}
js/message.js
: class Message {
constructor (text, x, y, font, color, visible) {
//propriedades
this.text = text;
this.x = x;
this.y = y;
this.font = font;
this.color = color;
this.visible = visible;
}
//metodos
fillText (cnv, ctx) {
if (this.visible) {
ctx.font = this.font;
switch (this.x) {
case "center":
this.x = (cnv.width - ctx.measureText(this.text).width) / 2;
break;
case "left":
this.x = 0;
break;
case "right":
this.x = cnv.width - ctx.measureText(this.text).width;
break;
}
switch (this.y) {
case "middle":
this.y = (cnv.height - parseInt(this.font)) / 2;
break;
case "top":
this.y = 0;
break;
case "bottom":
this.y = cnv.height - parseInt(this.font);
break;
}
ctx.fillStyle = this.color;
ctx.fillText(this.text, this.x, this.y, cnv.width);
}
}
}
js/script.js
: //carrega as imagens
var imgs = loadImgs("img/character/princess.png", "img/character/skeleton.png", "img/character/soldier.png");
//onload
onload = function () {
//variaveis
var cnv = document.getElementById("canvas");
var ctx = cnv.getContext("2d");
ctx.textBaseline = "top";
var msgs = [];
var chars = [];
var status = "start";
//cria as mensagens
msgs["title"] = new Message("UNDIVINE", "center", "middle", "80px 'Alfa Slab One'", "#fff", true);
//cria os personagens
chars["player"] = new Character(imgs["princess"], "left", "middle", false);
chars["skeleton"] = new Character(imgs["skeleton"], "center", "middle", false);
chars["soldier"] = new Character(imgs["soldier"], "right", "middle", false);
//eventos
cnv.addEventListener("click", function () {
if (status == "start") {
msgs["title"].visible = false;
for (var i in chars) {
chars[i].visible = true;
}
status = "play";
}
}, false);
addEventListener("keydown", function (e) {
if (status == "play") {
switch (e.keyCode) {
case 37:
chars["player"].walking = "left";
break;
case 38:
chars["player"].walking = "up";
break;
case 39:
chars["player"].walking = "right";
break;
case 40:
chars["player"].walking = "down";
break;
}
}
}, false);
addEventListener("keyup", function (e) {
if (status == "play") {
switch (e.keyCode) {
case 37:
chars["player"].stop("left");
break;
case 38:
chars["player"].stop("up");
break;
case 39:
chars["player"].stop("right");
break;
case 40:
chars["player"].stop("down");
break;
case 88:
chars["player"].acting = "slash";
break;
}
}
}, false);
//funcoes
function loop () {
requestAnimationFrame(loop);
if (status == "play") {
update();
}
render();
}
function update () {
for (var i in chars) {
chars[i].walk();
for (var j in chars) {
if (i != j) {
collision(chars[i], chars[j]);
action(chars[i], chars[j]);
}
}
}
}
function render () {
//limpa o canvas
ctx.clearRect(0, 0, cnv.width, cnv.height);
//desenha os personagens
for (var i in chars) {
chars[i].draw(cnv, ctx);
}
//escreve as mensagens
for (var i in msgs) {
msgs[i].fillText(cnv, ctx);
}
}
//inicia as funcoes
loop();
}
img/character/princess.png
: img/character/skeleton.png
: img/character/soldier.png
: Or,ifyouwanttodownloadeverythingfromGoogleDrive,theURLis link