AS3:小游戏“贪吃蛇”的实现

前几天在园子里看到有人用Silverlight做了一个"贪吃蛇",一时兴起也想用AS3.0做一个,虽然这个游戏已经被很多开发者做烂了,但是作为AS的初学者,重新做一遍也当是一种学习.

技术"难"点分析:

1.蛇身的构成
可以用数组来存储一堆小球,将它们排列成连续的直线即可

 

2.蛇身的移动
蛇头移动后,紧跟蛇头后的小球移动到蛇头原来的位置,然后...类推,后面的小球依次移动到前一个球的位置

 

3.碰撞检测
蛇头移动时,如果超出舞台边界,则Game Over了;同样蛇头如果遇到了蛇身,同样也Over.

 

4.食物的处理
在舞台上随机放一个小球,蛇头经过时,食物消失/蛇身加长(即数组中新追加一个小球)/食物重新随机定位

 

代码:
仍然用到Make Things Move中的著名Ball类,不过为了记录下次小球应该移动到的位置,增加二个变量nextx,nexty,Ball类的完整定义如下:

package {
	import flash.display.Sprite;

	//小球 类
	public class Ball extends Sprite {

		public var radius:uint;//半径
		public var color:uint;//颜色
		public var vx:Number=0;//x轴速度
		public var vy:Number=0;//y轴速度
		public var count:uint=0;//辅助计数变量
		public var isDragged=false;//是否正在被拖动
		public var vr:Number=0;//旋转速度
		public var mass:Number = 1;//质量
		public var nextx:Number=0;
		public var nexty:Number=0;

		public function Ball(r:Number=50,c:uint=0xff0000) {
			this.radius=r;
			this.color=c;
			init();
		}

		private function init():void {
			graphics.beginFill(color);
			graphics.drawCircle(0,0,radius);
			graphics.endFill();
		}
	}
}

当然,就本游戏而言,里面有很多变量都可以删除掉,这里为了完整起见保留下来了,游戏核心代码: 

import flash.utils.Timer;

var balls:Array;
var ballOriginCount:uint=3;
var radius:uint=10;
var sW:Number=stage.stageWidth;
var sH:Number=stage.stageHeight;
var tmr:Timer;
var speed:uint=200;//毫秒
var food:Ball;
var rows:uint = sW/(2*radius);
var cols:uint = sW/(2*radius);
var isDead:Boolean=false;
var isPause:Boolean=true;

//初始化
function init():void {
	balls = new Array();
	for (var i:uint=0; i<ballOriginCount; i++) {
		var b:Ball=new Ball(radius,Math.random()*0xffffff);
		balls.push(b);
		b.x=sW/2;
		b.y=sH/2;
		b.nextx=b.x;
		b.nexty=b.y;
		b.vx=b.width;
		addChild(b);
	}

	//刚开始时,让小球排成直线
	for (i=1; i<ballOriginCount; i++) {
		balls[i].x=balls[i-1].x-balls[i].width;
	}

	drawGrid();

	//初始化食物
	food=new Ball(radius*0.8,0x000000);
	checkFoodPosition();
	addChild(food);

	stage.addEventListener(KeyboardEvent.KEY_DOWN,keyDowmHandler);

	tmr=new Timer(speed);
	tmr.addEventListener(TimerEvent.TIMER,moveSnake);
	tmr.start();

	_gameover.visible=isDead;
	_notice.visible=isPause;
}

function restart():void {
	//先移除原有的蛇
	for (var i:int=balls.length-1; i>=0; i--) {
		removeChild(balls[i]);
	}

	//重来一切
	balls.length=0;
	ballOriginCount=3;
	for (i=0; i<ballOriginCount; i++) {
		var b:Ball=new Ball(radius,Math.random()*0xffffff);
		balls.push(b);
		b.x=sW/2;
		b.y=sH/2;
		b.nextx=b.x;
		b.nexty=b.y;
		b.vx=b.width;
		addChild(b);
	}

	for (i=1; i<ballOriginCount; i++) {
		balls[i].x=balls[i-1].x-balls[i].width;
	}

	isDead=false;
	isPause=false;
	_gameover.visible=isDead;
	_notice.visible=isPause;
}

//方向控制
function keyDowmHandler(e:KeyboardEvent):void {
	var b:Ball=balls[0];
	if (e.keyCode==Keyboard.SPACE) {
		isPause=! isPause;
		if (isDead) {
			restart();
		}

		_notice.visible=isPause;
	} else if (e.keyCode==Keyboard.DOWN&&b.vx!=0) {
		b.vy=b.width;
		b.vx=0;
	} else if (e.keyCode == Keyboard.UP && b.vx!=0) {
		b.vy=- b.width;
		b.vx=0;
	} else if (e.keyCode == Keyboard.LEFT && b.vy!=0) {
		b.vx=- b.width;
		b.vy=0;
	} else if (e.keyCode == Keyboard.RIGHT && b.vy!=0) {
		b.vx=b.width;
		b.vy=0;
	}
}

//画格子
function drawGrid() {
	for (var i:uint=radius; i<sW; i+=2*radius) {
		graphics.lineStyle(1,0,0.1);
		graphics.moveTo(i,0);
		graphics.lineTo(i,sH);
	}

	for (i=radius; i<sH; i+=2*radius) {
		graphics.lineStyle(1,0,0.1);
		graphics.moveTo(0,i);
		graphics.lineTo(sW,i);
	}
}

//蛇身的移动
function moveSnake(e:TimerEvent):void {
	//如果暂停或挂掉,则不处理
	if (isPause||isDead) {
		return;
	}

	var b:Ball=balls[0];
	b.nextx=b.x+b.vx;
	b.nexty=b.y+b.vy;
	for (var j:uint=1; j<ballOriginCount; j++) {
		var _b:Ball=balls[j];
		_b.nextx=balls[j-1].x;
		_b.nexty=balls[j-1].y;
	}
	for (j=0; j<ballOriginCount; j++) {
		balls[j].x=balls[j].nextx;
		balls[j].y=balls[j].nexty;
	}

	//边界检测
	if (b.x<b.radius||b.x>sW-b.radius||b.y<b.radius||b.y>sH-b.radius) {
		isDead=true;
		_gameover.visible=isDead;
		_notice.visible = isDead;
		return;
	}

	//检测蛇头是否咬到了自己
	for (j=1; j<ballOriginCount; j++) {
		var target:Ball=balls[j];
		if (b.x==target.x&&b.y==target.y) {
			isDead=true;
			_gameover.visible=isDead;
			_notice.visible = isDead;
			return;
		}
	}

	//如果蛇头经过食物,则表示吃掉了
	if (b.x==food.x&&b.y==food.y) {
		//trace("吃掉了!");
		var _newBall:Ball=new Ball(radius,Math.random()*0xffffff);
		_newBall.x=- radius;
		_newBall.y=- radius;
		balls.push(_newBall);
		addChild(_newBall);
		food.visible=false;

		ballOriginCount++;
	}
	makeFood();
}

//生成食物的新坐标
function makeFood() {
	if (food.visible==false) {
		checkFoodPosition();
		food.visible=true;
	}

	if (food.alpha==1) {
		food.alpha=0.5;
		food.scaleX=food.scaleY=1.2;
	} else {
		food.alpha=1;
		food.scaleX=food.scaleY=1;
	}
}

function checkFoodPosition():void {
	food.x=radius+int(Math.random()*rows)*2*radius;
	food.y=radius+int(Math.random()*cols)*2*radius;

	//检测食物的新坐标是否在“蛇身”上,如果是,则重新生成新坐标
	var isWrongPositon:Boolean=true;
	while (isWrongPositon) {
		var checkFlag:Boolean=true;
		for (var i:uint=0; i<ballOriginCount; i++) {
			var b:Ball=balls[i];
			if (b.x==food.y&&b.y==food.y) {
				checkFlag=false;
				break;
			}
		}
		if (!checkFlag) {
			food.x=radius+int(Math.random()*rows)*2*radius;
			food.y=radius+int(Math.random()*cols)*2*radius;
		}
		isWrongPositon=!checkFlag;
	}
}

init();

源文件下载: http://cid-2959920b8267aaca.office.live.com/self.aspx/Flash/Snake.rar

时间: 2024-07-31 21:09:08

AS3:小游戏“贪吃蛇”的实现的相关文章

Android开发之经典游戏贪吃蛇_Android

前言 这款游戏实现的思路和源码参考了Google自带的Snake的例子,其中修改了一些个人认为还不够完善的地方,加入了一些新的功能,比如屏幕上的方向操作盘,暂停按钮,开始按钮,退出按钮.另外,为了稍微增加些用户体验,除了游戏的主界面,本人自己新增了5个界面,分别是登陆界面,菜单界面,背景音乐设置界面,难度设置界面,还有个关于游戏的介绍界面.个人觉得在新手阶段,参考现成的思路和实现方式是难以避免的.重要的是我们需要有自己的理解,读懂代码之后,需要思考代码背后的实现逻辑,形成自己的思维.这样在下次开

Android开发之经典游戏贪吃蛇

前言 这款游戏实现的思路和源码参考了Google自带的Snake的例子,其中修改了一些个人认为还不够完善的地方,加入了一些新的功能,比如屏幕上的方向操作盘,暂停按钮,开始按钮,退出按钮.另外,为了稍微增加些用户体验,除了游戏的主界面,本人自己新增了5个界面,分别是登陆界面,菜单界面,背景音乐设置界面,难度设置界面,还有个关于游戏的介绍界面.个人觉得在新手阶段,参考现成的思路和实现方式是难以避免的.重要的是我们需要有自己的理解,读懂代码之后,需要思考代码背后的实现逻辑,形成自己的思维.这样在下次开

JavaScript 游戏 : 贪吃蛇

javascript 好像是最快的速度了... 说一说原理:是利用DOM的.<span>一条蛇,由蛇头到蛇尾</span>这样想到了什么?蛇尾就是这个span的第一个元素,蛇头就是最后一个元素啦.当然,调换前后也一样可以的. 然后建一个二维数组,当是地图的 x,y 坐标.然后,每节蛇也有它的 x,y 坐标,分别和上面的二维数组关连起来.这样就会得到蛇每一节的位置了,看看有没有超出数组上限或下限,GameOver.不过我这里为了体验一下速度,没这个GameOver条件,只有蛇头和蛇身

javascrpt加html实现的贪吃蛇小游戏

javascrpt有效代码17行 加上html代码的话,共25行 运行方法chrome或者 firefox 测试连接 http://lufylegend.com/html5/lufylegend/tcs.html 完整代 码如下 <!DOCTYPE html> <html> <body> <canvas id="myCanvas" width="240" height="240" style="

php实现贪吃蛇小游戏_php实例

贪吃蛇游戏是经典手机游戏,既简单又耐玩.通过控制蛇头方向吃蛋,使得蛇变长,从而获得积分.在诺基亚时代,风靡整个手机界,今天我们来看看另类的,如何使用php来实现贪吃蛇小游戏 废话不多说,代码奉上: control.php <!DOCTYPE html> <html> <head> <meta charset="utf-8"/> </head> <body>  <a href="control.php

java编写贪吃蛇小游戏_java

废话不多说,直接奉上代码: Frame.java package snake; import java.awt.Graphics; import java.awt.Menu; import java.awt.MenuBar; import java.awt.MenuItem; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import

纯js和css完成贪吃蛇小游戏demo_javascript技巧

本文实例为大家分享了js贪吃蛇小游戏demo,纯js和css完成,供大家参考,具体内容如下 <!doctype html> <html> <meta charset="utf-8"> <head> <style> *{ margin: 0; padding:0; } .content{ position: absolute; width: 500px; height: 500px; background-color: #212

js编写“贪吃蛇”的小游戏_javascript技巧

贪吃蛇儿时的回忆,今天刚好学习到这了,就刚好做了一个,也是学习了吧,需要掌握的知识: 1.JS函数的熟练掌握, 2.JS数组的应用, 3.JS小部分AJAX的学习 4.JS中的splice.shift等一些函数的应用, 基本上就这些吧,下面提重点部分: 前端的页面,这里可自行布局,我这边提供一个我自己的布局: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org

js贪吃蛇游戏实现思路和源码_javascript技巧

本文实例为大家分享了js贪吃蛇游戏的相关代码,供大家参考,具体内容如下 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>贪吃蛇小游戏</title> <style> *{margin:0; padding:0;} header { display: block; margin: 0 auto;