Html 5弧上点之间的碰撞

时间:2018-01-17 22:58:10

标签: javascript html html5 canvas collision

我正在开发一款使用射弹和屏蔽系统的游戏。玩家会按住“太空”来使用盾牌。我的计划是让弹丸射出敌人的盾牌(我已经实现了速度,所以我已经知道如何做到这一点)。我遇到的问题是碰撞,因为玩家旋转跟随鼠标我努力寻找创建盾牌的最佳方法但我最终确定了一个弧线,我使用了一些三角法来获得左边,左半边,中间, rightHalf,和弧/盾的右点。 The Player with Shield。问题是我无法从5个x / y坐标中得到碰撞(只是绘制弧线才显示我只是将点发送到服务器)。到目前为止,这就是我碰撞的原因:
p :玩家对象
自我:子弹对象
bot :一个基于角色所面向方向的变量(底部:真或假)
shieldLeft,sheildRight等:一个数组包含x和y坐标0表示x,1表示y

if (self.getDistance(p) < 32 && self.parent !== p.id)
        {
            if (p.isShielding == true)
            {

                switch(self.bot)
                {
                    case true:
                        if (self.x >= p.shieldRight[0] && self.x <= p.shieldLeft[0])
                        {
                            console.log("BOT X");
                            if ((self.y >= p.shieldLeft[1] || self.y >= p.shieldRight[1]) && self.y <= p.shieldMid[1])
                            {
                                console.log("BOT Y");
                                self.spdX = -self.spdX;
                                self.spdY = -self.spdY;
                            }
                        }


                    break;
                    case false:
                        if (self.x <= p.shieldRight[0] && self.x >= p.shieldLeft[0])
                        {
                            console.log("TOP X");
                            if ((self.y <= p.shieldLeft[1] || self.y <= p.shieldRight[1]) && self.y >= p.shieldMid[1])
                            {
                                console.log("TOP Y");
                                self.spdX = -self.spdX;
                                self.spdY = -self.spdY;
                            }
                        }
                    break;
                }



            }


        }

我真的很感激任何帮助,我不能继续游戏功能,直到实际上是一个游戏。谢谢!

1 个答案:

答案 0 :(得分:0)

&#13;
&#13;
<!doctype html>
<html>
	<head>
		<meta charset="utf-8">
		<style>
			body {
				background-color: black;
			}
			
			canvas {
				position: absolute;
				margin: auto;
				left: 0;
				right: 0;
				border: solid 1px white;
				border-radius: 10px;
				cursor: crosshair;
			}
		</style>
	</head>
	
	<body>
		<canvas id="canvas"></canvas>
		<script type="application/javascript">
		
			// Anonymous closure
			(function() {
			
				// Enforce strict rules for JS code
				"use strict";
				
				// App variables
				var canvasWidth = 180;
				var canvasHeight = 160;
				var canvas = null;
				var bounds = null;
				var ctx = null;
				var player = null;
				var projectiles = [];
					projectiles.length = 5;
				
				// Classes
				
				// Constructor function
				function Player(x,y) {
					this.x = x;
					this.y = y;
					this.dx = 0.0;
					this.dy = 0.0;
					this.rotation = 0.0;
					this.targetX = 0.0;
					this.targetY = 0.0;
					this.isShieldUp = false;
					this.isShieldRecharging = false;
					this.shieldPower = this.shieldPowerMax;
					this.left = false;
					this.right = false;
					this.up = false;
					this.down = false;
					window.addEventListener("keydown",this.onkeydown.bind(this));
					window.addEventListener("keyup",this.onkeyup.bind(this));
					window.addEventListener("mousemove",this.onmousemove.bind(this));
				}
				
				// shared properties/functions across all instances
				Player.prototype = {
					width: 10,
					height: 10,
					shieldRadius: 15.0,
					shieldArcSize: 3.0, // In Radians
					shieldPowerMax: 50.0,
					shieldPowerCharge: 0.5,
					shieldPowerDrain: 0.75,
					
					onkeydown: function(e) {
						switch(e.key) {
							case " ": this.isShieldUp = true && !this.isShieldRecharging; break;
							case "w": this.up = true; break;
							case "s": this.down = true; break;
							case "a": this.left = true; break;
							case "d": this.right = true; break;
						}
					},
					
					onkeyup: function(e) {
						switch(e.key) {
							case " ": this.isShieldUp = false; break;
							case "w": this.up = false; break;
							case "s": this.down = false; break;
							case "a": this.left = false; break;
							case "d": this.right = false; break;
						}
					},
					
					onmousemove: function(e) {
						this.targetX = e.clientX - bounds.left;
						this.targetY = e.clientY - bounds.top;
					},
				
					tick: function() {
						var x = (this.targetX - this.x);
						var y = (this.targetY - this.y);
						var l = Math.sqrt(x * x + y * y);
						x = x / l;
						y = y / l;
						this.rotation = Math.acos(x) * (y < 0.0 ? -1.0 : 1.0);
						
						if (this.isShieldUp) {
							this.shieldPower = this.shieldPower - this.shieldPowerDrain;
							if (this.shieldPower < 0.0) {
								this.shieldPower = 0.0;
								this.isShieldUp = false;
								this.isShieldRecharging = true;
							}
						} else {
							this.shieldPower = this.shieldPower + this.shieldPowerCharge;
							if (this.shieldPower > this.shieldPowerMax) {
								this.shieldPower = this.shieldPowerMax;
								this.isShieldRecharging = false;
							}
						}
						
						if (this.up) { --this.y; this.dy = -1; } else
						if (this.down) { ++this.y; this.dy = 1; } else { this.dy = 0; }
						if (this.left) { --this.x; this.dx = -1; } else
						if (this.right) { ++this.x; this.dx = 1; } else { this.dx = 0; }
					},
					
					render: function() {
						ctx.fillStyle = "darkred";
						ctx.strokeStyle = "black";
						ctx.translate(this.x,this.y);
						ctx.rotate(this.rotation);
						ctx.beginPath();
						ctx.moveTo(0.5 * this.height,0.0);
						ctx.lineTo(-0.5 * this.height,0.5 * this.width);
						ctx.lineTo(-0.5 * this.height,-0.5 * this.width);
						ctx.lineTo(0.5 * this.height,0.0);
						ctx.fill();
						ctx.stroke();
						
						if (this.isShieldUp) {
							ctx.strokeStyle = "cyan";
							ctx.beginPath();
							ctx.arc(0.0,0.0,this.shieldRadius,this.shieldArcSize * -0.5,this.shieldArcSize * 0.5,false);
							ctx.stroke();
						}
						
						ctx.rotate(-this.rotation);
						ctx.translate(-this.x,-this.y);
						ctx.fillStyle = "black";
						ctx.fillRect(canvasWidth - 80,canvasHeight - 20,75,15);
						ctx.fillStyle = this.isShieldRecharging ? "red" : "cyan";
						ctx.fillRect(canvasWidth - 75,canvasHeight - 15,65 * (this.shieldPower / this.shieldPowerMax),5);
					}
				};
				
				function Projectile(x,y,dx,dy) {
					this.x = x;
					this.y = y;
					this.dx = dx;
					this.dy = dy;
				}
				
				Projectile.prototype = {
					radius: 2.5,
					
					tick: function(player) {
						this.x = this.x + this.dx;
						this.y = this.y + this.dy;
						if (this.x + this.radius < 0.0) { this.x = canvasWidth + this.radius; }
						if (this.x - this.radius > canvasWidth) { this.x = -this.radius; }
						if (this.y + this.radius < 0.0) { this.y = canvasHeight + this.radius; }
						if (this.y - this.radius > canvasHeight) { this.y = -this.radius; }
						
						if (player.isShieldUp) {
							var px = (player.x - this.x);
							var py = (player.y - this.y);
							var pl = Math.sqrt(px * px + py * py);
							var ml = Math.sqrt(this.dx * this.dx + this.dy * this.dy);
							var mx = this.dx / ml;
							var my = this.dy / ml;
							px = px / pl;
							py = py / pl;
							
							if (Math.acos(px * mx + py * my) < player.shieldArcSize * 0.5 && pl < player.shieldRadius) {
								px = -px;
								py = -py;
								
								this.dx = this.dx - 2.0 * px * (this.dx * px + this.dy * py) + player.dx;
								this.dy = this.dy - 2.0 * py * (this.dx * px + this.dy * py) + player.dy;
							}
						}
					},
					
					render: function() {
						ctx.moveTo(this.x + this.radius,this.y);
						ctx.arc(this.x,this.y,this.radius,0.0,2.0 * Math.PI,false);
					}
				}
				
				// Game loop
				function loop() {
					// Tick
					player.tick();
					
					for (var i = 0; i < projectiles.length; ++i) {
						projectiles[i].tick(player);
					}
					// Render
					ctx.fillStyle = "#555555";
					ctx.fillRect(0,0,canvasWidth,canvasHeight);
					player.render();
					
					ctx.fillStyle = "white";
					ctx.strokeStyle = "black";
					ctx.beginPath();
					
					for (var i = 0; i < projectiles.length; ++i) {
						projectiles[i].render();
					}
					
					ctx.fill();
					ctx.stroke();
					//
					requestAnimationFrame(loop); // Runs the loop at 60hz
				}
				
				// "Main Method", executes after the page loads
				window.onload = function() {
					canvas = document.getElementById("canvas");
					canvas.width = canvasWidth;
					canvas.height = canvasHeight;
					bounds = canvas.getBoundingClientRect();
					ctx = canvas.getContext("2d");
					player = new Player(90.0,80.0);
					
					for (var i = 0; i < projectiles.length; ++i) {
						projectiles[i] = new Projectile(
							Math.random() * canvasWidth,
							Math.random() * canvasHeight,
							Math.random() * 2.0 - 1.0,
							Math.random() * 2.0 - 1.0
						);
					}
					
					loop();
				}
			
			})();
		
		</script>
	</body>
</html>
&#13;
&#13;
&#13;