解决方案 »
- Jquery加载UI core错误
- 添加头行声明后在Firefox中无法正常运行效果
- js调用问题?急
- 在按钮上单击出现对应的层,在空白处单击让相应的层消失(在线等)
- 如何实现在一文本框中输入的内容同时自动复制到另一文本框?
- 新手问题:关于javascript事件驱动,大家帮我看看。
- document.open()的问题
- 我这段改变文字大小的JAVASCRIPT脚本哪里出错了? 在线等,急!
- 拖入事件!高手请进
- 快被javascript搞疯了
- 新手关于setInterval()方法的小问题
- 求助编写一点javascript,点击按钮后调用某个图片(如素材\images\loading.gif)
ResetSnake: function() {
for (var i = 0; i < this._snakeArr.length; i++) {
document.body.removeChild(this._snakeArr[i]);
}
this._snakeArr.splice(0, this._snakeArr.length);
this._snakeArr = [];
},
get_mapDivObjId: function() { return this._mapDivObjId; },
set_mapDivObjId: function(value) { this._mapDivObjId = value; }, get_footDivObjId: function() { return this._footDivObjId; },
set_footDivObjId: function(value) { this._footDivObjId = value; }, get_bodyNum: function() { return this._bodyNum; },
set_bodyNum: function(value) { this._bodyNum = value; }, get_snakeGame: function() { return this._snakeGame; },
set_snakeGame: function(value) { this._snakeGame = value; }
}function keyDown(e)
{
var snakeGame = $Find("SnakeGame");
var direction = snakeGame.get_direction();
if(e.keyCode==37 && direction !== DirectEnum.Right) //向左
{
direction = DirectEnum.Left;
}
else if(e.keyCode == 38 && direction !== DirectEnum.Down) //向上
{
direction = DirectEnum.Up;
}
else if(e.keyCode == 39 && direction!==DirectEnum.Left) //向右
{
direction = DirectEnum.Right;
}
else if(e.keyCode == 40 && direction !== DirectEnum.Up) //向下
{
direction = DirectEnum.Down;
}
snakeGame.set_direction(direction);
}
//食物
function Food()
{
this._totalNum = 10;
this.consumeNum = 0;
this._footDivObjId=null;
}
Food.prototype = {
NewFood: function() {
var randomnum1 = Math.random();
var randomnum2 = Math.random(); var foodx = Math.round(870 * randomnum1) + 50;
var foody = Math.round(430 * randomnum2) + 50; var footDivObj = $Get(this._footDivObjId); footDivObj.style.left = foodx + "px";
footDivObj.style.top = foody + "px";
},
CheckFood: function() {
if (this._totalNum == this.consumeNum) {
return true;
}
return false;
},
ConsumeFood: function() {
this.consumeNum++;
},
ResetFoods: function() {
this.consumeNum = 0;
},
get_footDivObjId: function() { return this._footDivObjId; },
set_footDivObjId: function(value) { this._footDivObjId = value; },
get_totalNum: function() { return this._totalNum; },
set_totalNum: function(value) { this._totalNum = value; }
}
function GetItemPos(item) {
return { Left: item.offsetLeft, Right: item.offsetLeft + item.offsetWidth, Top: item.offsetTop, Bottom: item.offsetTop + item.offsetHeight };
}Number.prototype.GetWidth=function()
{
return isNaN(this)?0:this;
}
function GetRectangle(foodPos, snakePos) {
if ((snakePos.Left <= foodPos.Left) && (snakePos.Top <= foodPos.Top)) {
if (snakePos.Right < foodPos.Left || snakePos.Bottom < foodPos.Top) {
return -1;
}
else if ((snakePos.Left == foodPos.Left) && (snakePos.Top == foodPos.Top)) {
return 10;
}
else {
return (snakePos.Right - foodPos.Left) * (snakePos.Bottom - foodPos.Top);
}
}
else if ((snakePos.Left >= foodPos.Left) && (snakePos.Top <= foodPos.Top)) {
if (foodPos.Right < snakePos.Left || snakePos.Bottom < foodPos.Top) {
return -1;
}
else if ((snakePos.Left == foodPos.Left) && (snakePos.Top == foodPos.Top)) {
return 10;
}
else {
return (foodPos.Right - snakePos.Left) * (snakePos.Bottom - foodPos.Top);
}
}
else if ((snakePos.Left <= foodPos.Left) && (snakePos.Top >= foodPos.Top)) {
if (snakePos.Right < foodPos.Left || foodPos.Bottom < snakePos.Top) {
return -1;
}
else if ((snakePos.Left == foodPos.Left) && (snakePos.Top == foodPos.Top)) {
return 10;
}
else {
return (snakePos.Right - foodPos.Left) * (foodPos.Bottom - snakePos.Top);
}
}
else if ((snakePos.Left >= foodPos.Left) && (snakePos.Top >= foodPos.Top)) {
if (foodPos.Right < snakePos.Left || foodPos.Bottom < snakePos.Top) {
return -1;
}
else if ((snakePos.Left == foodPos.Left) && (snakePos.Top == foodPos.Top)) {
return 10;
}
else {
return (foodPos.Right - snakePos.Left) * (foodPos.Bottom - snakePos.Top);
}
}
}
</script>
</head>
<body onkeydown="keyDown(event)" style="overflow:hidden" scroll="no"> <div id="map_id" style="position:absolute;left:50px;top:50px;height:480px;width:920px;background-color:rgb(223,223,223)">
</div> <div id="food_div_id" style="position:absolute;left:300px;top:230px;height:20px;width:20px;border:white solid 1px;background-color:red;">
</div> <input type="button" id="start_bt_id" value="Start" onclick="InitGame();">
<input type="text" id="tx_id" readonly>
</body>
</html>
标题写的有点那个了,其实我是花三个小时改的,本来是开个玩笑,调侃一下那个花半天写游戏的兄弟。这种做法不对,不过没法改标题了,不好意思。
如果可以的话请版主帮我改成:“一个js oop的游戏,和交流一下心得(谢谢提供原始游戏代码的人)”
谢谢!
有兴趣的进来讨论讨论。
set_sd: function(value) { this._sd = value; }, get_isPass: function() { return this._isPass; },
set_isPass: function(value) { this._isPass = value; }, get_mode: function() { return this._mode; },
set_mode: function(value) { this._mode = value; }, get_timer: function() { return this._timer; },
set_timer: function(value) { this._timer = value; }, get_foodsId: function() { return this._foodsId; },
set_foodsId: function(value) { this._foodsId = value; }, get_direction: function() { return this._direction; },
set_direction: function(value) { this._direction = value; },邯郸学步,这些东西又长又不香.而且对俄罗斯方块,贪食蛇之类极度审美疲劳了.
http://topic.csdn.net/u/20090729/09/32164988-96af-4c15-a9d4-b873764b0535.html第34楼的代码是修改后的代码。
http://topic.csdn.net/u/20090624/12/d9579640-aa24-4560-9479-1f6e4247afd0.html
System.out.println("太奇妙了");
}
呵呵,谢谢你的源码,游戏可以,不过你的代码有很多地方是可以再优化的,即使不用OOP。
一起努力吧。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<title>wujinjian </title>
<script type="text/javascript">
var ModeEnum = { First: "first", Next: "next" } //定义一个枚举,代表游戏的模式,一个json字符串的例子
var DirectEnum = { Left: "left", Right: "right", Up: "up", Down: "down" };//定义一个枚举,代表方向。
var components = {}; //哈希表,主要保存js对象
var handlers = {}; //哈希表,主要保存handler
function $Find(id) {
/// <summary>
/// 根据id查找相应的对象
/// </summary>
/// <param name="id">对象id</param>
if (!components[id]) {
if (id == "SnakeGame") {
components[id] = new SnakeGame(); //new 一个游戏对象
}
else if (id == "snake") {
components[id] = new Snake(); //new 一个蛇对象
}
else if (id == "foods") {
components[id] = new Food(); //new 一个食物对象
}
}
return components[id];
}
function $Get(id) {
/// <summary>
/// 包装getElementById
/// </summary>
/// <param name="id">对象id</param>
return document.getElementById(id);
}
function $CreateDelegate(instance, method) {
/// <summary>
/// 创建一个委托
/// </summary>
/// <param name="instance"></param>
/// <param name="method" type="Function"></param>
/// <returns type="Function"></returns>
return function() { //返回一个函数定义
return method.apply(instance, arguments);
}
}
function InitGame() {
/// <summary>
/// 初始化游戏
/// </summary>
$Get("tx_id").value = "第 1 关";
var snakeGame = $Find("SnakeGame");
if (snakeGame) {
snakeGame.set_snakeId("snake");
snakeGame.set_foodsId("foods");
snakeGame.ResetStart();
}
}
function SnakeGame() {
/// <summary>
/// 定义一个游戏对象,包含若干字段
/// </summary>
this._sd = 250; //速度默认为250,也就是250毫秒执行一次SnakeMove,该值可以通过get_sd从对象外部获取,或者set_sd从外部设置
this._timer = null;
this._foodsId = null;
this._snakeId = null;
this._direction = null;
this._mode = ModeEnum.First;
this._isPass = false;
}
SnakeGame.prototype = {
ResetStart: function() {
/// <summary>
/// 初始化一个游戏对象
/// </summary>
document.getElementById("start_bt_id").disabled = true; if (this._mode == ModeEnum.First)
$Get("tx_id").value = "第 1 关";
this._timer = null;
this._direction = DirectEnum.Right;
var foods = $Find(this._foodsId);
var snake = $Find(this._snakeId);
snake.set_footDivObjId("food_div_id");
snake.set_mapDivObjId("map_id");
foods.set_footDivObjId("food_div_id");
foods.ResetFoods();
snake.ResetSnake();
snake.Initialize();
this._startGame();
},
_startGame: function() {
/// <summary>
/// 开始进行游戏
/// </summary>
this._timer = setInterval(this.raise_move, this._sd); //this.raise_move执行自定义事件
},
// _moveSnake: function() {
// this.raise_move();
// },
IsDivSuperpose: function(snakeDivObj, footDivObj) {
/// <summary>
/// 判断蛇是否吃到食物
/// </summary>
/// <param name="snakeDivObj" type="dom element">dom元素蛇</param>
/// <param name="footDivObj" type="dom element">dom元素食物</param>
var snakePos = GetItemPos(snakeDivObj); //获取蛇头位置
var foodPos = GetItemPos(footDivObj); //获取食物位置
var rectangle = GetRectangle(foodPos, snakePos); //获取蛇与食物的交叉面积
if (rectangle > 0) { //说明吃到食物
var foods = $Find(this._foodsId);
foods.ConsumeFood(); //消耗一个食物
if (!foods.CheckFood()) { //如果食物没消耗完
foods.NewFood(); //新增一个食物
var snake = $Find(this._snakeId);
snake.AddSnakeBody(); //往蛇上再加一节
}
else {
// this.set_isPass(true);
this.GoToNextLevel();
} }
},
GoToNextLevel: function() {
/// <summary>
/// 进入下一关
/// </summary>
alert("恭喜你进入下一关");
this._sd = this._sd - 10; //速度
$Get("tx_id").value = "第 " + ($Get("tx_id").value.split(" ")[1] - 0 + 1) + " 关";
this._mode = ModeEnum.Next;
var foods = $Find(this._foodsId);
var snake = $Find(this._snakeId);
this.ResetStart();
// InitGame();
},
IsKill: function(snakeDivObj, mapDivObj) {
/// <summary>
/// 判断蛇是否触到边界
/// </summary>
/// <param name="snakeDivObj" type="dom element">dom元素蛇</param>
/// <param name="footDivObj" type="dom element">dom元素食物</param>
var snakePos = GetItemPos(snakeDivObj);
var panelRectangle = GetItemPos(mapDivObj);
if (snakePos.Right >= panelRectangle.Right ||
snakePos.Left <= panelRectangle.Left || snakePos.Top <= panelRectangle.Top
|| snakePos.Bottom >= panelRectangle.Bottom) {
this._gameOver();
return true;
}
return false;
},
_gameOver: function() {
/// <summary>
/// 游戏结束
/// </summary>
var obj = clearInterval(this._timer);
var snake = $Find(this._snakeId);
snake.ClearSnakeHandler(); //清除handler
alert("失败!");
$Get("start_bt_id").disabled = false;
},
get_sd: function() { return this._sd; },
set_sd: function(value) { this._sd = value; }, get_isPass: function() { return this._isPass; },
set_isPass: function(value) { this._isPass = value; }, get_mode: function() { return this._mode; },
set_mode: function(value) { this._mode = value; }, get_timer: function() { return this._timer; },
set_timer: function(value) { this._timer = value; }, get_foodsId: function() { return this._foodsId; },
set_foodsId: function(value) { this._foodsId = value; }, get_direction: function() { return this._direction; },
set_direction: function(value) { this._direction = value; },
add_move: function(handler) {
/// <summary>
/// add handler
/// </summary>
handlers["move"] = handler;
},
remove_move: function(handler) {
/// <summary>
/// remove handler
/// </summary>
handlers["move"] = null;
delete handlers["move"];
},
raise_move: function(eventargs) {
/// <summary>
/// implement handler
/// </summary>
var handler = handlers["move"];
if (handler) {
handler(this, eventargs);
}
},
get_snakeId: function() { return this._snakeId; },
set_snakeId: function(value) { this._snakeId = value; }
}
function Snake() {
/// <summary>
/// 定义一个蛇对象
/// </summary>
this._bodyNum = 3;
this._snakeGame = "SnakeGame";
this._snakeArr = [];
this._footDivObjId = null;
this._mapDivObjId = null;
this._moveDelegate = $CreateDelegate(this, this.SnakeMove);
this.snakeBodyW_H = 20;
}
Snake.prototype = {
AddSnakeBody: function() {
/// <summary>
/// 添加一个蛇身
/// </summary>
this._snakeArr[this._snakeArr.length] = this._createSnakeBody();
},
_createSnakeBody: function() {
/// <summary>
/// 创建一个蛇身
/// </summary>
var snakeDiv = document.createElement("div"); snakeDiv.style.position = "absolute";
snakeDiv.style.left = "120px";
snakeDiv.style.top = "300px";
snakeDiv.style.width = this.snakeBodyW_H + "px";
snakeDiv.style.height = this.snakeBodyW_H + "px"; document.body.appendChild(snakeDiv); return snakeDiv;
},
Initialize: function() {
/// <summary>
/// 初始化蛇对象
/// </summary>
for (var i = 0; i < this._bodyNum; i++) {
this.AddSnakeBody();
}
var snakeGame = $Find(this._snakeGame);
if (snakeGame) {
snakeGame.add_move(this._moveDelegate); //把事件绑定到游戏对象上
}
},
ClearSnakeHandler: function() {
/// <summary>
/// 清除handler
/// </summary>
var snakeGame = $Find(this._snakeGame);
if (snakeGame) {
snakeGame.remove_move(this._moveDelegate);
}
},
SnakeMove: function() {
/// <summary>
/// 移动蛇
/// </summary>
var last = this._snakeArr[this._snakeArr.length - 1]; //把最后一个元素移到第一个
for (var i = this._snakeArr.length - 1; i > 0; i--) {
this._snakeArr[i] = this._snakeArr[i - 1];
this._snakeArr[i].style.backgroundColor = "red";
this._snakeArr[i].style.border = "white solid 1px";
}
this._snakeArr[0] = last; var first = this._snakeArr[0];
var second = this._snakeArr[1]; first.style.backgroundColor = "blue"; var secondPos = GetItemPos(second);
var footDivObj = $Get(this._footDivObjId);
var mapDivObj = $Get(this._mapDivObjId);
var snakeGame = $Find(this._snakeGame);
if (snakeGame) {
var direction = snakeGame.get_direction();
if (direction == DirectEnum.Left) {
first.style.left = secondPos.Left - this.snakeBodyW_H + "px";
first.style.top = secondPos.Top + "px";
}
else if (direction == DirectEnum.Up) {
first.style.left = secondPos.Left + "px";
first.style.top = secondPos.Top - this.snakeBodyW_H + "px";
}
else if (direction == DirectEnum.Right) {
first.style.left = secondPos.Left + this.snakeBodyW_H + "px";
first.style.top = secondPos.Top + "px";
}
else if (direction == DirectEnum.Down) {
first.style.left = secondPos.Left + "px";
first.style.top = secondPos.Top + this.snakeBodyW_H + "px";
}
if (!snakeGame.IsKill(first, mapDivObj))
snakeGame.IsDivSuperpose(first, footDivObj);
} }, ResetSnake: function() {
/// <summary>
/// 重置蛇对象
/// </summary>
for (var i = 0; i < this._snakeArr.length; i++) {
document.body.removeChild(this._snakeArr[i]);
}
this._snakeArr.splice(0, this._snakeArr.length);
this._snakeArr = [];
},
get_mapDivObjId: function() { return this._mapDivObjId; },
set_mapDivObjId: function(value) { this._mapDivObjId = value; }, get_footDivObjId: function() { return this._footDivObjId; },
set_footDivObjId: function(value) { this._footDivObjId = value; }, get_bodyNum: function() { return this._bodyNum; },
set_bodyNum: function(value) { this._bodyNum = value; }, get_snakeGame: function() { return this._snakeGame; },
set_snakeGame: function(value) { this._snakeGame = value; }
} function keyDown(e) {
/// <summary>
/// keydown事件
/// </summary>
var snakeGame = $Find("SnakeGame");
var direction = snakeGame.get_direction();
if (e.keyCode == 37 && direction !== DirectEnum.Right) //向左
{
direction = DirectEnum.Left;
}
else if (e.keyCode == 38 && direction !== DirectEnum.Down) //向上
{
direction = DirectEnum.Up;
}
else if (e.keyCode == 39 && direction !== DirectEnum.Left) //向右
{
direction = DirectEnum.Right;
}
else if (e.keyCode == 40 && direction !== DirectEnum.Up) //向下
{
direction = DirectEnum.Down;
}
snakeGame.set_direction(direction);
}
//食物
function Food() {
/// <summary>
/// 初始化食物对象
/// </summary>
this._totalNum = 10;
this.consumeNum = 0;
this._footDivObjId = null;
}
Food.prototype = {
NewFood: function() {
/// <summary>
/// 新增一个食物
/// </summary>
var randomnum1 = Math.random();
var randomnum2 = Math.random(); var foodx = Math.round(870 * randomnum1) + 50;
var foody = Math.round(430 * randomnum2) + 50; var footDivObj = $Get(this._footDivObjId); footDivObj.style.left = foodx + "px";
footDivObj.style.top = foody + "px";
},
CheckFood: function() {
/// <summary>
/// 检测食物是否消耗完
/// </summary>
if (this._totalNum == this.consumeNum) {
return true;
}
return false;
},
ConsumeFood: function() {
/// <summary>
/// 消耗一个食物
/// </summary>
this.consumeNum++;
},
ResetFoods: function() {
/// <summary>
/// 重置对象
/// </summary>
this.consumeNum = 0;
},
get_footDivObjId: function() { return this._footDivObjId; },
set_footDivObjId: function(value) { this._footDivObjId = value; }, get_totalNum: function() { return this._totalNum; },
set_totalNum: function(value) { this._totalNum = value; }
}
function GetItemPos(item) {
return { Left: item.offsetLeft, Right: item.offsetLeft + item.offsetWidth, Top: item.offsetTop, Bottom: item.offsetTop + item.offsetHeight };
} Number.prototype.GetWidth = function() {
/// <summary>
/// 给number原型添加一个自定义方法,使用例子:10.GetWidth();
/// </summary>
return isNaN(this) ? 0 : this;
}
function GetRectangle(foodPos, snakePos) {
/// <summary>
/// 获取矩形的四个点位置
/// </summary>
if ((snakePos.Left <= foodPos.Left) && (snakePos.Top <= foodPos.Top)) {
if (snakePos.Right < foodPos.Left || snakePos.Bottom < foodPos.Top) {
return -1;
}
else if ((snakePos.Left == foodPos.Left) && (snakePos.Top == foodPos.Top)) {
return 10;
}
else {
return (snakePos.Right - foodPos.Left) * (snakePos.Bottom - foodPos.Top);
}
}
else if ((snakePos.Left >= foodPos.Left) && (snakePos.Top <= foodPos.Top)) {
if (foodPos.Right < snakePos.Left || snakePos.Bottom < foodPos.Top) {
return -1;
}
else if ((snakePos.Left == foodPos.Left) && (snakePos.Top == foodPos.Top)) {
return 10;
}
else {
return (foodPos.Right - snakePos.Left) * (snakePos.Bottom - foodPos.Top);
}
}
else if ((snakePos.Left <= foodPos.Left) && (snakePos.Top >= foodPos.Top)) {
if (snakePos.Right < foodPos.Left || foodPos.Bottom < snakePos.Top) {
return -1;
}
else if ((snakePos.Left == foodPos.Left) && (snakePos.Top == foodPos.Top)) {
return 10;
}
else {
return (snakePos.Right - foodPos.Left) * (foodPos.Bottom - snakePos.Top);
}
}
else if ((snakePos.Left >= foodPos.Left) && (snakePos.Top >= foodPos.Top)) {
if (foodPos.Right < snakePos.Left || foodPos.Bottom < snakePos.Top) {
return -1;
}
else if ((snakePos.Left == foodPos.Left) && (snakePos.Top == foodPos.Top)) {
return 10;
}
else {
return (foodPos.Right - snakePos.Left) * (foodPos.Bottom - snakePos.Top);
}
}
}
</script>
</head>
<body onkeydown="keyDown(event)" style="overflow:hidden" scroll="no"> <div id="map_id" style="position:absolute;left:50px;top:50px;height:480px;width:920px;background-color:rgb(223,223,223)">
</div> <div id="food_div_id" style="position:absolute;left:300px;top:230px;height:20px;width:20px;border:white solid 1px;background-color:red;">
</div> <input type="button" id="start_bt_id" value="Start" onclick="InitGame();">
<input type="text" id="tx_id" readonly>
</body>
</html>
说的好~
lz都this.xx了,还get_xx浪费资源,你var xx再 get_xx还说的过去...
另外我也觉既然是炫技术炫标准,那就用继承撒,要不然和面向过程又有多大区别呢
set_mapDivObjId: function(value) { this._mapDivObjId = value; }, get_footDivObjId: function() { return this._footDivObjId; },
set_footDivObjId: function(value) { this._footDivObjId = value; }, get_bodyNum: function() { return this._bodyNum; },
set_bodyNum: function(value) { this._bodyNum = value; }, get_snakeGame: function() { return this._snakeGame; },
set_snakeGame: function(value) { this._snakeGame = value; }
可见楼主思维受C#或Java禁锢之深!!!
不要以为把js代码来一番C# like或者Java like了就是善举,这样的确像zengtan1021所说的既长又不香!
什么脚穿什么鞋嘛。同时,基于RPWT,你应该列出原作者及其链接。
如果你硬是要用get_Name和set_Name,那么A对象的Name就应该是var Name而不是this.Name
实话说我觉得直接使用this.xx不是一个很好的习惯,通过get,set我完全可以再使用之前验证数据的有效性,也就是我可以做到js强类型化
又比如我可以在执行IsKill: function(snakeDivObj, mapDivObj)之前验证snakeDivObj或者mapDivObj是否是dom元素,不是则抛出异常。。
当你觉得你的代码篇幅太长了,bug太多了,你就用继承吧,如果你觉得没这样的烦恼,那你别管它种类再少,实现起来再容易,也不用管它什么继承不继承,除非你要炫耀你的技术
=============================
当你觉得你的代码篇幅太长了,bug太多了,你就用继承吧
==============
这句话我不敢苟同,代码多了就用继承?呵呵
http://topic.csdn.net/u/20090729/09/32164988-96af-4c15-a9d4-b873764b0535.html 再次谢谢这个兄弟。
如果可以,版主请给我加到楼顶。谢谢!
简单的东西不见得没有经济价值,甚至就像lz做的贪食蛇,比如你把它做成online的
那你仅仅是浏览器+js,是办不到的,或者效率太低无法太多人在线,如果有个提供
高性能联网对象集的外壳来代替浏览器?如果不代替浏览器,而是把这些基本对象集做
成一个控件,下载安装或者在线安装?然后再解决如何提升游戏平台粘度的问题,那就是又一个
开心网啊。
http://u.download.csdn.net/source/1536151鄙视一下转载不注明出处的人.