Created
December 30, 2017 03:46
-
-
Save chaz4/afb318e15c021aba219d4d03738267b4 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset="UTF-8" /> | |
<title>Collision 3</title> | |
</head> | |
<body> | |
<canvas id="maincv"></canvas> | |
<script> | |
const PLAYER_SPEED = 3; | |
const PLAYER_JUMP = 6; | |
const PLAYER_GRAVITY= 0.3; | |
const PLAYER_FALL = 10; | |
window.addEventListener('load',init); | |
document.onkeydown = function(e){ | |
if(e.keyCode==37)keybuff.left = true; | |
if(e.keyCode==39)keybuff.right = true; | |
if(e.keyCode==32)keybuff.space = true; | |
} | |
document.onkeyup = function(e){ | |
if(e.keyCode==37)keybuff.left = false; | |
if(e.keyCode==39)keybuff.right = false; | |
if(e.keyCode==32)keybuff.space = false; | |
} | |
class Sprite { | |
constructor(x,y,w,h,color){ | |
this.x = x; | |
this.y = y; | |
this.w = w; | |
this.h = h; | |
this.color = color; | |
} | |
getTop(){ | |
return this.y - this.h/2; | |
} | |
getBottom(){ | |
return this.y + this.h/2; | |
} | |
draw(){ | |
ctx.fillStyle = this.color; | |
ctx.fillRect(this.x-this.w/2, this.y-this.h/2, this.w, this.h); | |
} | |
hitTest(ax,ay,group) { | |
for (let sp in group) { | |
let opponent = group[sp]; | |
let sx = Math.abs(ax - opponent.x); | |
let sy = Math.abs(ay - opponent.y); | |
let sw = this.w/2 + opponent.w/2; | |
let sh = this.h/2 + opponent.h/2; | |
//ヒットしている時 | |
if ( (sx < sw) && (sy < sh) ) return opponent; | |
} | |
return null; | |
} | |
} | |
class Player extends Sprite { | |
constructor(x,y){ | |
super(x,y,30,40,'blue'); | |
this.vsp = 0; | |
} | |
update(){ | |
let mx=0,jump=false; | |
//キー入力取得 | |
if(keybuff.left)mx=-1; | |
if(keybuff.right)mx=1; | |
if(keybuff.space)jump=true; | |
let hsp = mx * PLAYER_SPEED; | |
//地面に接地しているか | |
let isGround = false; | |
if(this.hitTest(this.x, this.y+1, blockGroup)) isGround = true; | |
//重力を加える | |
if(this.vsp < PLAYER_FALL) this.vsp += PLAYER_GRAVITY; | |
//移動床との衝突 | |
let hit = this.hitTest(this.x, this.y+this.vsp, moveFloorGroup); | |
if(hit){ | |
let playerBottom = this.getBottom(); //プレイヤーの下端 | |
let opponentTop = hit.getTop(); //衝突相手の上端 | |
if(this.vsp>=0 && playerBottom<opponentTop){ | |
while(!this.hitTest(this.x, this.y+1, moveFloorGroup)) this.y++; | |
this.vsp = 0; | |
this.x += hit.moveX; | |
isGround = true; | |
} | |
} | |
//ジャンプ | |
if(jump && isGround) this.vsp = -PLAYER_JUMP; | |
//水平方向の衝突 | |
let sign = getSign(hsp); | |
if(this.hitTest(this.x+hsp, this.y, blockGroup)){ | |
while(!this.hitTest(this.x+sign, this.y, blockGroup)){ | |
this.x += sign; | |
} | |
hsp = 0; | |
} | |
this.x += hsp; | |
//垂直方向の衝突 | |
sign = getSign(this.vsp); | |
if(this.hitTest(this.x, this.y+this.vsp, blockGroup)){ | |
while(!this.hitTest(this.x, this.y+sign, blockGroup)){ | |
this.y += sign; | |
} | |
this.vsp = 0; | |
} | |
this.y += this.vsp; | |
} | |
} | |
class MoveFloor extends Sprite { | |
constructor(x,y,dir){ | |
super(x,y,40,15,'yellow'); | |
this.moveX = dir * 1.5; //移動速度 | |
this.minX = x-64; //左の限度位置 | |
this.maxX = x+64; //右の限度位置 | |
} | |
update(){ | |
this.x += this.moveX; | |
if(this.x<=this.minX || this.x>=this.maxX) this.moveX = -this.moveX; | |
} | |
} | |
let cv,ctx; | |
let x=50,y=50; | |
let keybuff = {left:false, right:false, up:false, down:false}; | |
let blockGroup = []; | |
let moveFloorGroup = []; | |
let player = new Player(50,200); | |
blockGroup.push(new Sprite(280,150,50,50,'green')); | |
blockGroup.push(new Sprite(150,200,50,50,'green')); | |
blockGroup.push(new Sprite(200,250,400,40,'green')); | |
moveFloorGroup.push(new MoveFloor(80,130,-1)); | |
moveFloorGroup.push(new MoveFloor(200,80,1)); | |
function init(){ | |
cv = document.getElementById('maincv'); | |
ctx = cv.getContext('2d'); | |
cv.width = 400; | |
cv.height = 300; | |
requestAnimationFrame(update); | |
} | |
function update(){ | |
requestAnimationFrame(update); | |
player.update(); | |
for(let sp in moveFloorGroup) {moveFloorGroup[sp].update();} | |
render(); | |
} | |
function render(){ | |
ctx.fillStyle = "gray"; | |
ctx.fillRect(0,0,cv.width,cv.height); | |
for(let sp in blockGroup) {blockGroup[sp].draw();} | |
for(let sp in moveFloorGroup) {moveFloorGroup[sp].draw();} | |
player.draw(); | |
} | |
function getSign(val){ | |
if(val < 0){ | |
return -1; | |
}else if(val > 0){ | |
return 1; | |
}else{ | |
return 0; | |
} | |
} | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment