我正在尝试制作一种向上滚动的街机射击游戏。我一直陷在如何从玩家向敌人将要向上弹子弹的问题上。我正在使用setInterval在玩家所在的位置重复射击动作,但是子弹只会跟随战斗机重新设置间隔,每次玩家移动指定的距离。
有帮助吗?
此刻是我的代码。
谢谢。
var project, ctx, img, img2, width, height, mid, midh, startPx, startPy, audio,interval,bulletStartPx,bulletStartPy;
var score = 0;
function setUp() {
project = document.getElementById("project");
ctx = project.getContext("2d");
width = 505;
height = 900;
mid = width/2;
midh = height/2;
startPx = width/2-30;
startPy = height-150;
audio = new Audio("bgm.mp3");
audio.play();
img = new Image();
img2 = new Image();
img.src = "bg.png";
img2.src = "fighterjet.png"
img.onload = function(){
ctx.shadowColor = "#ffffff";
ctx.shadowBlur = 15;
ctx.drawImage(img, 0, 0);
ctx.drawImage(img2, startPx, startPy)
}
window.addEventListener("keydown", checkKeyPress);
}
function drawObject(x, y) {
ctx.drawImage(img2, startPx, startPy)
}
function checkKeyPress(event) {
if (event.keyCode == "87") {//W(UP)
ctx.clearRect(0,0,width,height);
if (startPy >= 20) {
startPy -= 20;
}
ctx.drawImage(img, 0, 0);
ctx.drawImage(img2, startPx, startPy)
} else if (event.keyCode == "83") {//S(DOWN)
ctx.clearRect(0,0,width,height);
if (startPy <= 785) {
startPy += 20;
}
ctx.drawImage(img, 0, 0);
ctx.drawImage(img2, startPx, startPy)
} else if (event.keyCode == "65") {//A(LEFT)
ctx.clearRect(0,0,width,height);
if (startPx >= 0) {
startPx -= 20;
}
ctx.drawImage(img, 0, 0);
ctx.drawImage(img2, startPx, startPy)
} else if (event.keyCode == "68") {//D(RIGHT)
ctx.clearRect(0,0,width,height);
if (startPx <= 410) {
startPx += 20;
}
ctx.drawImage(img, 0, 0);
ctx.drawImage(img2, startPx, startPy)
} else if (event.keyCode == "72") {
for (let i = 0; i < 6; i++) {
bullets();
}
}
}
function bullets() {
return setInterval(function(){
bulletStartPx = startPx+48;
bulletStartPy = startPy-30;
ctx.fillStyle = "gold"
ctx.beginPath();
ctx.arc(bulletStartPx,bulletStartPy,5,0,2*Math.PI);
ctx.fill();
score += 25; }, 100);
}
function GameOver(){
document.getElementById('bm').pause();
ctx.font = '30px Courier New'
ctx.filltext('GAME OVER', mid, midh)
ctx.filltext('Your score was: '+score, mid, midh+40)
}
function showScore(){
ctx.fillStyle = '#ff0000'
ctx.font = '18px Courier New'
ctx.text(score, width-10, 15)
}
/*
function bullet(){
this.x = startPx;
this.y = startPy - 10;
this.draw = function() {
ctx.fillStyle = "#b20808";
ctx.shadowColor = "#b20808";
ctx.shadowBlur = 15;
this.y -= bulletSpeed;
ctx.fillRect(this.x, this.y, 2, 8);
}
}
function fireGun(){
if (event.keyCode == "32") {
bullet();
}
}*/
<!DOCTYPE html>
<html>
<head>
<title>Project</title>
<meta charset="utf-8">
<script src="project.js" type="text/javascript" defer></script>
</head>
<body>
<h1>Arcade Shooter</h1>
<fieldset>
<legend><h2>Instructions:</h2></legend>
<h3>Press W, A, S, D to Move</h3>
<h3>Press Space Bar to Fire</h3>
<h3>Goal: Survive as long as you can!</h3>
</fieldset>
<br>
<canvas id="project" style="border-style: solid" width=505 height=900 ></canvas>
<br>
<input id="start" type="button" value="START THE GAME" onclick="setUp()" style="width: 300px">
</body>
</html>
答案 0 :(得分:0)
1)您需要重新定义全局变量,以便跟踪所有内容:
[assembly: ExportRenderer(typeof(ListView), typeof(MyLVRenderer))]
public class MyLVRenderer : ListViewRenderer
{
//UITableViewSource originalSource;
protected override void OnElementChanged(ElementChangedEventArgs<ListView> e)
{
base.OnElementChanged(e);
UITableViewSource originalSource = (UIKit.UITableViewSource)Control.Source;
Control.Source = new MyLVSource(originalSource);
}
}
public class MyLVSource : UITableViewSource
{
UITableViewSource originalSource;
public MyLVSource(UITableViewSource origSource)
{
originalSource = origSource;
}
public override nint RowsInSection(UITableView tableview, nint section)
{
return originalSource.RowsInSection(tableview, section);
}
public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)
{
return originalSource.GetCell(tableView, indexPath);
}
public override nfloat GetHeightForFooter(UITableView tableView, nint section)
{
return originalSource.GetHeightForFooter(tableView, section);
}
public override nfloat GetHeightForRow(UITableView tableView, NSIndexPath indexPath)
{
nfloat origHeight = originalSource.GetHeightForRow(tableView, indexPath);
// calculate your own row height here
return origHeight + (indexPath.Row +1) * 10;
}
}
2)仅检查checkKeyPress(event)函数中的动作,包括fireGun动作:
var gameData = {
interval: null, // Controls the refresh
redrawRequired: false, // Flag
allBullets: [], // Moving bullets
defaultBulletSpeed: 20 // Bullet speed
}
3)这是定义子弹对象和firegun()函数的方法:
function checkKeyPress(event) {
if (event.keyCode == "87") {//87 W(UP)
if (startPy >= 20) {
startPy -= 20;
gameData.redrawRequired = true;
}
} else if (event.keyCode == "83") {//83 S(DOWN)
if (startPy <= 785) {
startPy += 20;
gameData.redrawRequired = true;
}
} else if (event.keyCode == "65") {//65 A(LEFT)
if (startPx >= 0) {
startPx -= 20;
gameData.redrawRequired = true;
}
} else if (event.keyCode == "68") {//68 D(RIGHT)
if (startPx <= 410) {
startPx += 20;
gameData.redrawRequired = true;
}
} else if (event.keyCode == "72") { // 72 SPACEBAR ?? Actually H
fireGun();
}
}
4)然后使用一个主要功能(refreshGame)和另一个功能检查是否有要更新的项目符号(refreshBullets),决定何时重新绘制画布:
function Bullet() {
// Object defining a bullet.
this.x = startPx;
this.y = startPy - 10;
this.bulletSpeed = gameData.defaultBulletSpeed;
}
Bullet.prototype.draw = function () {
// Draws the bullet on canvas...
ctx.fillStyle = "#b20808";
ctx.shadowColor = "#b20808";
ctx.shadowBlur = 15;
ctx.fillRect(this.x, this.y, 2, 8);
}
Bullet.prototype.move = function () {
// Moves the bullet...
this.y = this.y - this.bulletSpeed;
}
function fireGun() {
var newBullet = new Bullet();
gameData.allBullets.push(newBullet);
}
5)最后,您初始化整个过程,包括setUp()函数中的setInterval:
function refreshBullets() {
var i = 0;
var currentBullet;
// Start by eliminating bullets out of the screen...
while (i < gameData.allBullets.length) {
currentBullet = gameData.allBullets[i];
if (currentBullet.y < -10) {
gameData.allBullets.splice(i, 1); // Remove the bullet outside of the screen.
} else {
currentBullet.move();
gameData.redrawRequired = true;
i += 1; // Next bullet...
}
}
}
function refreshGame() {
refreshBullets();
if (gameData.redrawRequired) {
ctx.clearRect(0,0,width,height);
ctx.drawImage(img, 0, 0, width, height);
ctx.drawImage(img2, startPx, startPy);
for (var i = 0; i < gameData.allBullets.length; i++) {
gameData.allBullets[i].draw();
}
}
gameData.redrawRequired = false;
}
注意:
由于性能问题,使用setInterval的canvas方法被认为是一种不好的方法。尝试搜索“使用画布刷新JavaScript间隔”,还有其他方法可以解决该问题。 refreshRequired变量/属性只是一个占位符,用于解释解决方法。实际上,您必须不断重绘场景,因为背景,目标和威胁将在飞机下方移动,并且您将在此过程中更新得分。
在编写代码之前,您应该设计游戏,其目标,角色,控制方式,界限,水平是什么。......纸和笔是一个好的开始。问题是,当您开始手工编写代码时,问自己的那一刻就会卡住,我该如何使子弹与目标相撞?如果我可以改用导弹呢?最后,由于您试图在创建另一个问题的同时解决一个问题,因此您的代码将变得很繁重且占用大量处理器资源……只是一个建议;)
答案 1 :(得分:0)
您不想每次发射子弹时都使用setInterval。 您想在整个游戏中使用一个setInterval,以便在每个游戏对象上调用更新或绘制功能。 例如
var game={
//this is a list of items in the game I want to move around or do stuff
//nothing there yet
objects:[]
}
//this is a bullet object which can be created calling new bullet()
function Bullet(){
//IM CHEATING HERE. DON'T DRAW TO THE DOM FOR GAMES
//this is just a shortcut instead of drawing on a canvas
this.object=document.createElement('div');
this.object.style.width="10px";
this.object.style.height="10px";
this.object.style.position='absolute';
this.object.style.top="100px";
this.object.style.backgroundColor='red';
document.body.appendChild(this.object)
///
//these hold the bullet's current location on screen
this.x=100;
this.y=100;
//this is the update function that gets called every frame
this.update=function(){
//I'm updating the bullet's y position.
this.y-=10;
if(this.y>0){
//don't draw to the dom like this. use canvas like you were doing.
this.object.style.top=this.y+"px";
}
}
}
//now let's add a bullet to the game
game.objects.push(new bullet());
//the function that updates each of our objects
function runGame(){
for(var i=0;i<game.objects.length;i++){
game.objects[i].update();
}
}
//start the game
setInterval(runGame, 1000)
注意:请勿像这样在DOM上绘制。像以前一样使用画布。我只是将dom用作演示的快捷方式