知识共享-Android版贪吃蛇源码及分析(雷惊风)
贪吃蛇源码分析

Android ---snake源代码分析代码结构分析:Snake :主游戏窗口SnakeView :游戏视图类,是实现游戏的主体类TileView :一个处理图片或其它Coordinate :这是一个包括两个参数,用于记录X轴和Y轴简单类,其中包括一个比较函数.RefshHandler :用于更新视图Snake这个类是游戏的主游戏窗口,是框架容器,1.游戏的开始:oncreate此外的亮点是:setContentView(yout.snake_layout);设置窗口的布局文件,这里Android123给大家说明的是,这里的snake_layout使用了自定义资源标签的方式,大家注意学习:这里我们可以看到来自SnakeView这个派生类的名称,由于Android内部的R.资源不包含SnakeView类,所以我们必须写清楚Package,比如com.exmple.android.snake.SnakeView 然后和其他控件使用一样,都是一个id然后宽度、高度、以及自定义的标签tileSize(尾巴长度),如下:<com.example.android.snake.SnakeViewandroid:id="@+id/snake"android:layout_width="fill_parent"android:layout_height="fill_parent"tileSize="12"/>2.onPause:关于这点,大家可以参考下在我blog中关于active生命周期/admin/blogs/379826在玩游戏过程中,如果有来电或是其它事件中断,这时应该把当前状态保存。
以便返回时,还可以继续玩游戏。
这就使用onSaveInstanceState实现保存当前状态。
TileView注:此部分解析来自: Android示例程序Snake贪食蛇代码分析(三)TileView,从名称上不难看出这是一个方砖类,就是生成一个方块。
贪吃蛇游戏源代码

begin();
}
//----------------------------------------------------------------------
//keyPressed():按键检测
//----------------------------------------------------------------------
void begin()
{
if(snakeModel==null||!snakeModel.running)
{
snakeModel=new SnakeModel(this,canvasWidth/nodeWidth,
this.canvasHeight/nodeHeight);
(new Thread(snakeModel)).start();
//GreedSnake():初始化游戏界面
//----------------------------------------------------------------------
public GreedSnake()
{
//设置界面元素
mainFrame=new JFrame("GreedSnake");
*要点分析:
*1)数据结构:matrix[][]用来存储地图上面的信息,如果什么也没有设置为false,
* 如果有食物或蛇,设置为true;nodeArray,一个LinkedList,用来保存蛇的每
* 一节;food用来保存食物的位置;而Node类是保存每个位置的信息。
超简单贪吃蛇c语言代码编写

超简单贪吃蛇c语言代码编写贪吃蛇其实就是实现以下几步——1:蛇的运动(通过“画头擦尾”来达到蛇移动的视觉效果)2:生成食物3:蛇吃食物(实现“画头不擦尾”)4:游戏结束判断(也就是蛇除了食物,其余东西都不能碰)#include<stdio.h>#include<stdlib.h>#include<windows.h>#include<conio.h>#include<time.h>#define width 60#define hight 25#define SNAKESIZE 200//蛇身的最长长度int key=72;//初始化蛇的运动方向,向上int changeflag=1;//用来标识是否生成食物,1表示蛇还没吃到食物,0表示吃到食物int speed=0;//时间延迟struct {int len;//用来记录蛇身每个方块的坐标int x[SNAKESIZE];int y[SNAKESIZE];int speed;}snake;struct{int x;int y;}food;void gotoxy(int x,int y)//调用Windows的API函数,可以在控制台的指定位置直接操作,这里可暂时不用深究{COORD coord;coord.X = x;coord.Y = y;SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord); }//■○void drawmap(){//打印图框for (int _y = 0; _y < hight; _y++){for (int x = 0; x < width; x+=2){if (x == 0 || _y == 0 || _y == hight - 1 || x == width - 2){gotoxy(x, _y);printf("■");}}}//打印蛇头snake.len=3;snake.x[0]=width/2;snake.y[0]=hight/2;gotoxy(snake.x[0],snake.y[0]);printf("■");//打印蛇身for(int i=1;i<snake.len;i++){snake.x[i]=snake.x[i-1];snake.y[i]=snake.y[i-1]+1;gotoxy(snake.x[i],snake.y[i]);printf("■");}//初始化食物的位置food.x=20;food.y=20;gotoxy(food.x,food.y);printf("○");}/**控制台按键所代表的数字*“↑”:72*“↓”:80*“←”:75*“→”:77*/void snake_move()//按键处理函数{int history_key=key;if (_kbhit()){fflush(stdin);key = _getch();key = _getch();}if(changeflag==1)//还没吃到食物,把尾巴擦掉{gotoxy(snake.x[snake.len-1],snake.y[snake.len-1]);printf(" ");}for(int i=snake.len-1;i>0;i--){snake.x[i]=snake.x[i-1];snake.y[i]=snake.y[i-1];}if(history_key==72&&key==80)key=72;if(history_key==80&&key==72)key=80;if(history_key==75&&key==77)key=75;if(history_key==77&&key==75)key=77;switch(key){case 72:snake.y[0]--;break;case 75:snake.x[0]-= 2;break;case 77:snake.x[0]+= 2;break;case 80:snake.y[0]++;break;}gotoxy(snake.x[0],snake.y[0]);printf("■");gotoxy(0,0);changeflag=1;}void creatfood(){if(snake.x[0] == food.x && snake.y[0] == food.y)//只有蛇吃到食物,才能生成新食物{changeflag=0;snake.len++;if(speed<=100)speed+=10;while(1){srand((unsigned int) time(NULL));food.x=rand()%(width-6)+2;//限定食物的x范围不超出围墙,但不能保证food.x 为偶数food.y=rand()%(hight-2)+1;for(int i=0;i<snake.len;i++){if(food.x==snake.x[i]&&food.y==snake.y[i])//如果产生的食物与蛇身重合则退出break;}if(food.x%2==0)break;//符合要求,退出循环}gotoxy(food.x,food.y);printf("○");}}bool Gameover(){//碰到围墙,OVERif(snake.x[0]==0||snake.x[0]==width-2)return false;if(snake.y[0]==0||snake.y[0]==hight-1) return false;//蛇身达到最长,被迫OVERif(snake.len==SNAKESIZE)return false;//头碰到蛇身,OVERfor(int i=1;i<snake.len;i++){if(snake.x[0]==snake.x[i]&&snake.y[0]==snake.y[i])return false;}return true;}int main(){system("mode con cols=60 lines=27");drawmap();while(Gameover()){snake_move();creatfood();Sleep(350-speed);//蛇的移动速度}return 0;}。
贪吃蛇游戏实现思路及源代码

贪吃蛇游戏实现思路及源代码HTML5 贪吃蛇游戏实现思路及源代码点评:游戏难点是怎么模拟贪吃蛇的移动。
如果只是一个方块的话显然很简单。
但是当蛇的长度变长之后要怎么样控制,下面为大家简要介绍下具体的实现,感兴趣的朋友可以参考下,希望对大家有所帮助游戏操作说明通过方向键控制贪吃蛇上下左右移动。
贪吃蛇吃到食物之后会变长一个长度。
游戏具体实现游戏难点是怎么模拟贪吃蛇的移动。
如果只是一个方块的话显然很简单。
但是当蛇的长度变长之后要怎么样控制每个方块的移动呢?如果观察蛇的移动,可以发现,从蛇的头部到尾部,每个方块在下一时刻的位置就是它的前一个方块在当前时刻的位置。
因此我们需要做的只是控制贪吃蛇的头部的运动。
其他部分的位置都可以依次类推。
另外一个值得注意的问题是贪吃蛇吃下食物之后,新增加的方块应该放在哪个位置。
答案就是在下一时刻,新增加的方块应该出现在当前时刻的尾部位置。
因此,在吃下食物之后应该在更新蛇的每个位置之前,增加一个方块,并且将其位置设定在当前时刻的尾部位置。
然后在当前时刻更新出了新增方块之外的所有方块的位置index.htmlsnake.js复制代码代码如下:var canvas;var ctx;var timer;//measuresvar x_cnt = 15;var y_cnt = 15;var unit = 48;var box_x = 0;var box_y = 0;var box_width = 15 * unit;var box_height = 15 * unit;var bound_left = box_x;var bound_right = box_x + box_width;var bound_up = box_y;var bound_down = box_y + box_height;//imagesvar image_sprite;//objectsvar snake;var food;var food_x;var food_y;//functionsfunction Role(sx, sy, sw, sh, direction, status, speed, image, flag) {this.x = sx;this.y = sy;this.w = sw;this.h = sh;this.direction = direction;this.status = status;this.speed = speed;this.image = image;this.flag = flag;}function transfer(keyCode){switch (keyCode){case 37:return 1;case 38:return 3;case 39:return 2;case 40:return 0;}}function addFood(){//food_x=box_x+Math.floor(Math.random()*(box_width-unit));//food_y=box_y+Math.floor(Math.random()*(box_height-unit));food_x = unit * Math.floor(Math.random() * x_cnt);food_y = unit * Math.floor(Math.random() * y_cnt);food = new Role(food_x, food_y, unit, unit, 0, 0, 0, image_sprite, true);}function play(event){var keyCode;if (event == null){keyCode = window.event.keyCode;window.event.preventDefault();}else{keyCode = event.keyCode;event.preventDefault();}var cur_direction = transfer(keyCode);snake[0].direction = cur_direction;}function update(){//add a new part to the snake before move the snakeif (snake[0].x == food.x && snake[0].y == food.y){var length = snake.length;var tail_x = snake[length - 1].x;var tail_y = snake[length - 1].y;var tail = new Role(tail_x, tail_y, unit, unit, snake[length - 1].direction, 0, 0, image_sprite, true); snake.push(tail);addFood();}//modify attributes//move the headswitch (snake[0].direction){case 0: //downsnake[0].y += unit;if (snake[0].y > bound_down - unit) snake[0].y = bound_down - unit; break;case 1: //leftsnake[0].x -= unit;if (snake[0].x < bound_left)snake[0].x = bound_left;break;case 2: //rightsnake[0].x += unit;if (snake[0].x > bound_right - unit) snake[0].x = bound_right - unit; break;case 3: //upsnake[0].y -= unit;if (snake[0].y < bound_up)snake[0].y = bound_up;break;}//move other part of the snakefor (var i = snake.length - 1; i >= 0; i--) {if (i > 0)//snake[i].direction=snake[i-1].direction; {snake[i].x = snake[i - 1].x;snake[i].y = snake[i - 1].y;}}}function drawScene(){ctx.clearRect(box_x, box_y, box_width, box_height); ctx.strokeStyle = "rgb(0,0,0";ctx.strokeRect(box_x, box_y, box_width, box_height); //detection collisions//draw imagesfor (var i = 0; i < snake.length; i++){ctx.drawImage(image_sprite, snake[i].x, snake[i].y); }ctx.drawImage(image_sprite, food.x, food.y);}function init(){canvas = document.getElementById("scene");ctx = canvas.getContext('2d');//imagesimage_sprite = new Image();image_sprite.src = "images/sprite.png";image_sprite.onLoad = function (){}//ojectssnake = new Array();var head = new Role(0 * unit, 0 * unit, unit, unit, 5, 0, 1, image_sprite, true); snake.push(head);window.addEventListener('keydown', play, false);addFood();setInterval(update, 300); //notesetInterval(drawScene, 30); }。
安卓贪吃蛇源代码

安卓贪吃蛇源代码#define M 200#include"graphics.h"#include<stdlib.h>#include<stdio.h>#include<string.h>#include<iostream.h>#include<dos.h>#include<conio.h>#include <windows.h>#define LEFT 97//A#define RIGHT 100//D#define DOWN 115//S#define UP 119//W#define Esc 0x011bint i,key;int score=0;int gamespeed=250;//游戏速度可根据实际情况自行调整struct Food{int x;//食物的横坐标int y;//食物的纵坐标int yes;//判断是否要出现食物的变量}food;//食物的结构体struct Snake{int x[M];int y[M];int node;//蛇的节数int direction;//蛇的移动方向int life;//蛇的生命,0表示活着,1表示死亡}snake;void Init();//图形驱动void Close();//图形结束void DrawK();//开始画面void GamePlay();//玩游戏的具体过程void GameOver();//游戏结束void PrScore();//输出成绩void main()//主函数{Init();//图形驱动DrawK();//开始画面GamePlay();//玩游戏的具体过程Close();//图形结束}void Init()//图形驱动{int gd=DETECT,gm;initgraph(&gd,&gm," ");/*此处为turboc的路径,读者可以根据自己的电脑而改*/cleardevice();}void DrawK()//开始画面,左上角坐标为(50,40),右下角坐标为(610,460)的围墙{setbkcolor(GREEN);setcolor(LIGHTRED);setlinestyle(0,0,5);//设置线型for(i=50;i<=600;i+=10)//画围墙{rectangle(i,40,i+10,49);//上边rectangle(i,451,i+10,460);//下边}for(i=40;i<=450;i+=10){rectangle(50,i,59,i+10);//左边rectangle(601,i,610,i+10);//右边}}void GamePlay()//玩游戏的具体过程{rand();//随机数发生器food.yes=1;//1表示需要出现新食物,0表示已经存在食物snake.life=0;//蛇活着snake.direction=1;//方向往右snake.x[0]=100;snake.y[0]=100;//舌头坐标snake.x[1]=110;snake.y[1]=100 ;snake.node=2;//蛇的节数PrScore();//输出分数while(1)//可重复玩游戏,按ESC键结束{while(!kbhit())//在没有按键的情况下,蛇自己移动身体{if(food.yes==1)//需要出现新食物{food.x=rand()%400+60;food.y=rand()%350+60;while(food.x%10!=0)//食物随即出现后必须让食物能够在整格内,这样才能让蛇迟到food.x++;while(food.y%10!=0)food.y++;food.yes=0;//画面上有食物了}if(food.yes==0)//画面上有食物就要显示{setcolor(GREEN);rectangle(food.x,food.y,food.x+10,food.y-10);}for(i=snake.node-1;i>0;i--)//蛇的每个环节往前移动,也就是贪吃蛇的关键算法{snake.x[i]=snake.x[i-1];snake.y[i]=snake.y[i-1];}switch(snake.direction)//1,2,3,4表示上下左右四个方向,通过这个判断来移动蛇头{case 1:snake.x[0]+=10;break;case 2:snake.x[0]-=10;break;case 3:snake.y[0]-=10;break;case 4:snake.y[0]+=10;break;}for(i=3;i<snake.node;i++)//从蛇的第四节开始判断是否撞到自己了,因为蛇头为两节,第三节不可能拐过来{if(snake.x[i]==snake.x[0]&&snake.y[i]==snake.y[0]){GameOver();//显示失败snake.life=1;break;}}if(snake.x[0]<55||snake.x[0]>595||snake.y[0]<55||snake.y[0]>455)//蛇是否撞到墙壁{GameOver();//本次游戏结束snake.life=1;//蛇死}if(snake.life==1)//以上两种判断以后,如果蛇死就跳出内循环,重新开始break;if(snake.x[0]==food.x&&snake.y[0]==food.y)//吃到食物以后{setcolor(0);//把画面上的食物去掉rectangle(food.x,food.y,food.x+10,food.y-10);snake.x[snake.node]=-20;snake.y[snake.node]=-20;//新的一节先放在看不见得位置,下次循环就取前一节的位置snake.node++;//蛇的身体长一节food.yes=1;score+=10;PrScore();//输出新的得分}setcolor(WHITE);//画出蛇for(i=0;i<snake.node;i++)rectangle(snake.x[i],snake.y[i],snake.x[i]+10,snake.y[i]-10);Sleep(gamespeed);setcolor(0);//用黑色去除蛇的最后一节rectangle(snake.x[snake.node-1],snake.y[snake.node-1],snake.x[snake.node-1]+10,snake.y[snake.node-1]-10);}if(snake.life==1)//如果蛇死就跳出循环break;key=getchar();//接受案件if(key==Esc)//按ESC键退出break;else if(key==UP&&snake.direction!=4)snake.direction=3;else if(key==RIGHT&&snake.direction!=2)snake.direction=1;else if(key==LEFT&&snake.direction!=1)snake.direction=2;else if(key==DOWN&&snake.direction!=3)snake.direction=4;}//endwhile(1)}void GameOver()//游戏结束{cleardevice();PrScore();setcolor(RED);outtextxy(100,100,"我会回来的!!!!!");getch();}void PrScore()//输出成绩{char str[10];setfillstyle(SOLID_FILL,YELLOW);bar(50,15,220,35);setcolor(6);sprintf(str,"score:%d",score);outtextxy(55,20,str);}void Close()//图形结束{getch();closegraph();}。
贪吃蛇源码和设计思路

长为 1°。具体要求如下:
1. 三角函数计算程序采用汇编语言编写;
2. 汇编语言程序可以采用独立汇编模块,也可以采用嵌入式汇编,鼓励尝试两种方法;
3. 主程序可以采用 Turbo C 或 Visual C++。
解:
① 设计思路
输入输出可以用C语言编写,主程序用汇编语言编写,汇编语言中有计算sin,cos,
TIME DW ?
YLABEL DB ?
;蛋的位置
XLABEL DB ?
SSIZE DB 14
;蛇的长度
BEFOR DB 13
;蛇前一次的长度
AA DW ?
;前一次的时间
TAILX DB ?
;蛇尾的位置
TAILY DB ?
DATA ENDS
STACK SEGMENT STACK
DB 100 DUP(?)
④ 遇到的问题及解决方法
遇到的最大问题是蛇的自动移动,开始时由于出栈入栈的方式记录上次读取的时间,由
于初始时没有入栈的就先出栈,导致报错。后来实在受不了了,就采用了 DI 寄存器记
录。
开始时,每次按键时没有更新上次时间,使得按键和自动前进可能发生冲突,导致记录
的是两次前的时间值。后来加上一条语句就好了。
//求正切
FDIV ST,ST(1)
//求余切
FSTP COT
FSTP TAN
}
cout<<SIN<<"______"<<COS<<"______"<<TAN<<"_______"<<COT<<endl;
汇编语言写的贪吃蛇小游戏源代码

DATA SEGMENTdw 0,0snk db 1blk db 32food db 3tal1 db 4tal2 db 2adrs db 5len db ?pst db ?addrs dw ?frow db ?fcol db ?hwrt db ?gmov db 'game over press r to restart press q to quit $'score1 db 'score :$'score2 db ?score0 db 1zero db 48writer db 'Developer: Geniusdot $'email db ': geniusdotgmail.$'msg1 db 'The way to play the game:$'way db ' press w to up ,press s to down,press a to left,press d to right$' msg db 'Press any key(except a,s,d,w) to start$'DATA ENDSSTACK SEGMENT stackdb 200 dup(0)STACK ENDSCODE SEGMENTASSUME CS:CODE,DS:DATA,SS:STACKstart:mov ax,datamov ds,axmov ax,0mov es,axmov frow,10mov fcol,6mov dh,10mov dl,26mov ah,2int 10hmov ah,9lea dx,msg1 int 21hmov dh,11 mov dl,7 mov ah,2 mov bh,0int 10hmov ah,9lea dx,way int 21hmov dh,12 mov dl,20 mov ah,2 mov bh,0int 10hmov ah,9lea dx,msg int 21hmov ah,0int 16hmov ah,6 mov al,0 mov ch,0 mov cl,0 mov dh,24 mov dl,79 mov bh,10 int 10hmov dh,0 mov dl,0 mov ah,2 mov bh,0int 10hmov ah,9lea dx,score1 int 21hmov dl,15 mov ah,2 mov bh,0int 10hlea dx,writerint 21hmov ah,9lea dx,emailint 21hmov score2,48push es:[9*4] ;将原int9入口地址保存pop ds:[0]push es:[9*4+2]pop ds:[2]mov word ptr es:[9*4],offset int9 ;更改中断向量表mov es:[9*4+2],csjmp aawrite macro row,col,cnt ;宏定义用于向当前光标处输出字符push bxpush cxpush dxmov dh,rowmov dl,colmov ah,2mov bh,0int 10hmov ah,9mov bl,11mov cx,1lea di,cnt ;50mov al,[di]int 10hpop dxpop cxpop bxendmreadh macro row,col ;宏定义用于读出当前光标处字符push dxpush bxmov dh,rowmov dl,colmov ah,2mov bh,0int 10hmov ah,08hint 10hmov pst,alpop bxpop axpop dxendmwnear macro ;宏定义只用在readcg宏中当readcg的所有判断都不成立调用此宏local wnext1local wnext2local wnext3local wnext4push dxdec dhreadh dh,dlcmp pst,1jne wnext1write dh,dl,tal2jmp wnext4wnext1:inc dhdec dlreadh dh,dlcmp pst,1jne wnext2write dh,dl,tal2jmp wnext4wnext2:inc dhinc dlreadh dh,dlcmp pst,1jne wnext3write dh,dl,tal2jmp wnext4dec dhinc dlreadh dh,dlcmp pst,1jne wnext4write dh,dl,tal2wnext4:pop dxendmreadcg macro row,col ;宏定义用于改变判断出来的字符local tnup,tnup1,tnup2,tnlf,tnlf1,tnlf2,tndn,tndn1,tndn2,tnrt,tnrt1,tnrt2,gooutpush bxpush axpush dxwrite dh,dl,tal1dec rowreadh dh,dlcmp pst,4jne tnup1jmp tnup2tnup1:jmp near ptr tnuptnup2:write dh,dl,blkinc dhinc dhreadh dh,dlcmp pst,1jne tnupwrite dh,dl,tal2jmp near ptr goouttnup:pop dxpush dxdec colreadh dh,dlcmp pst,4jne tnlf1jmp tnlf2tnlf1:jmp near ptr tnlf tnlf2:write dh,dl,blkinc dlinc dlreadh dh,dlcmp pst,1jne tnlfwrite dh,dl,tal2 jmp near ptr goout tnlf:pop dxpush dxinc rowreadh dh,dlcmp pst,4jne tndn1jmp tndn2tndn1:jmp near ptr tndn tndn2:write dh,dl,blk dec dhdec dhreadh dh,dlcmp pst,1jne tndnwrite dh,dl,tal2 jmp near ptr goout tndn:pop dxpush dxinc colreadh dh,dlcmp pst,4jne tnrt1jmp tnrt2tnrt1:jmp near ptr tnrt tnrt2:write dh,dl,blk dec dldec dlreadh dh,dlcmp pst,1jne tnrtwrite dh,dl,tal2jmp near ptr goouttnrt:pop dxpush dxwneargoout:pop dxpop axpop bxendmaddone: ;此标号功能是将蛇身增加一push dxinc score2mov dh,1mov dl,0mov cx,23cmpad1:push cxmov cx,79cmpad2:readh dh,dlcmp pst,2jne nextad3jmp nextad4nextad3:jmp near ptr nextadnextad4:write dh,dl,snkdec dhreadh dh,dlcmp pst,4jne natupwrite dh,dl,tal2dec dhwrite dh,dl,tal1jmp outonatup:inc dhreadh dh,dlcmp pst,4jne natlfwrite dh,dl,tal2dec dlwrite dh,dl,tal1jmp outonatlf:inc dhinc dlreadh dh,dlcmp pst,4jne natdnwrite dh,dl,tal2inc dhwrite dh,dl,tal1jmp outonatdn:dec dhinc dlreadh dh,dlcmp pst,4jne natrtwrite dh,dl,tal2inc dlwrite dh,dl,tal1 natrt:outo:pop cxjmp near ptr endad nextad:inc dljmp nextad2chgad2:jmp near ptr cmpad2 nextad2:loop chgad2sub dl,79inc dhpop cxjmp nextad1chgad1:jmp near ptr cmpad1loop chgad1endad:pop dxjmp near ptr crtfaa: ;从这开始产生最原始的蛇mov addrs,offset turnrightmov dh,10mov dl,1mov cx,3write dh,dl,tal1inc dlwrite dh,dl,tal2wrt:inc dlwrite dh,dl,snkloop wrtmov len,6mov ax,0jmp wrt1ovflw: ;当蛇碰壁或自身转到此游戏结束mov ah,6mov al,0mov ch,0mov cl,0mov dh,24mov dl,79mov bh,7int 10hmov dh,17mov dl,17mov ah,2mov bh,0int 10hmov ah,9lea dx,gmovint 21hmov ax,0 ;恢复int9中断mov es,axpop es:[9*4]push ds:[2]pop es:[9*4+2]stop:mov ah,0int 16hcmp al,'r'je aa1jmp aa2aa1:jmp near ptr startaa2:cmp al,'q'jne stopjmp near ptr exitwrt1: ;此处蛇行走过程的无限循环call dlypush dxinc dhcmp dh,25je ovflwinc dlcmp dl,80je ovflwpop dxpush dxdec dhcmp dh,0je ovflwdec dlcmp dl,-1je ovflwpop dxpush dxlea ax,turnrightcmp addrs,axjne tonxt2inc dlreadh dh,dlcmp pst,1je tonxt1cmp pst,2je tonxt1cmp pst,4je tonxt1jmp tonxt2 tonxt1:jmp ovflw tonxt2:pop dxpush dxlea ax,turnup cmp addrs,ax jne tonxt4dec dhreadh dh,dl cmp pst,1je tonxt3cmp pst,2je tonxt3cmp pst,4je tonxt3jmp tonxt4 tonxt3:jmp ovflw tonxt4:pop dxpush dxlea ax,turndown cmp addrs,ax jne tonxt6inc dhreadh dh,dl cmp pst,1je tonxt5cmp pst,2je tonxt5cmp pst,4je tonxt5jmp tonxt6 tonxt5:jmp ovflw tonxt6:pop dxpush dxlea ax,turnback cmp addrs,axjne tonxt8dec dlreadh dh,dlcmp pst,1je tonxt7cmp pst,2je tonxt7cmp pst,4je tonxt7jmp tonxt8tonxt7:jmp ovflwtonxt8:pop dxjmp nextacrtf1:jmp near ptr addone crtf:call rand1call rand2inc frowmov ah,frowmov al,fcolpush dxmov dh,1mov dl,0push cxmov cx,23check1:push cxmov cx,79check2:readh dh,dlcmp pst,1je nextncmp pst,2je nextncmp pst,4je nextnjmp nextnn nextn:cmp ax,dxje crtfnextnn:inc dlloop check2inc dhsub dl,79pop cxloop check1pop cxpop dxwrite frow,fcol,food nexta:mov ah,frowmov al,fcolcmp ax,dxje crtf12jmp crtf13crtf12:jmp near ptr crtf1 crtf13:push dxcmp score2,58jl normalmov score2,49inc score0 normal:mov dh,0mov dl,8write dh,dl,score2 add dl,score0write dh,dl,zero pop dxcmp adrs,17je jmp1cmp adrs,145je jmp1cmp adrs,31je jmp2cmp adrs,159je jmp2cmp adrs,32je jmp3cmp adrs,160je jmp3cmp adrs,30je jmp4cmp adrs,158je jmp4jmp addrsjmp1:lea ax, turndowncmp ax,addrsje jmp2mov addrs,offset turnupjmp near ptr turnupjmp2:lea ax,turnupcmp ax,addrsje jmp1mov addrs,offset turndownjmp near ptr turndownjmp3:lea ax,turnbackcmp ax,addrsje jmp4mov addrs,offset turnrightjmp near ptr turnrightjmp4:lea ax,turnrightcmp ax,addrsje jmp3mov addrs,offset turnbackjmp near ptr turnbackturnright: ;此处实现蛇向左走push dxmov dh,1mov dl,0mov cx,23cmpr1:push cxmov cx,79cmpr2:readh dh,dlcmp pst,2je nextr4jmp near ptr nextrnextr4:readcg dh,dlpop cxjmp near ptr endrnextr:inc dljmp nextr2chgr2:jmp near ptr cmpr2nextr2:loop chgr2sub dl,79inc dhpop cxjmp nextr1chgr1:jmp near ptr cmpr1nextr1:loop chgr1endr:pop dxinc dlwrite dh,dl,snkjmp near ptr wrt1turnup: ;此处实现蛇向上走push dxmov dh,1mov dl,0mov cx,23cmpu1:push cxmov cx,79cmpu2:readh dh,dlcmp pst,2jne nextu3jmp nextu4nextu3:jmp near ptr nextunextu4:readcg dh,dlpop cxjmp near ptr endunextu:inc dljmp nextu2chgu2:jmp near ptr cmpu2nextu2:loop chgu2sub dl,79inc dhpop cxjmp nextu1chgu1:jmp near ptr cmpu1nextu1:loop chgu1endu:pop dxdec dhwrite dh,dl,snkjmp near ptr wrt1turndown: ;此处实现蛇向下走push dxmov dh,1mov dl,0mov cx,23cmpd1:push cxmov cx,79cmpd2:readh dh,dlcmp pst,2jne nextd3jmp nextd4nextd3:jmp near ptr nextdnextd4:readcg dh,dlpop cxjmp near ptr enddnextd:inc dljmp nextd2chgd2:jmp near ptr cmpd2nextd2:loop chgd2sub dl,79inc dhpop cxjmp nextd1chgd1:jmp near ptr cmpd1nextd1:loop chgd1endd:pop dxinc dhwrite dh,dl,snkjmp near ptr wrt1turnback: ;此处实现蛇向右走push dxmov dh,1mov dl,0mov cx,23cmpb1:push cxmov cx,79cmpb2:readh dh,dlcmp pst,2jne nextb3jmp nextb4nextb3:jmp near ptr nextbnextb4:readcg dh,dlpop cxjmp near ptr endbnextb:jmp nextb2chgb2:jmp near ptr cmpb2nextb2:loop chgb2sub dl,79inc dhpop cxjmp nextb1chgb1:jmp near ptr cmpb1nextb1:loop chgb1endb:pop dxdec dlwrite dh,dl,snkjmp near ptr wrt1exit:mov ax,0 ;恢复int9中断mov es,axpush ds:[0]pop es:[9*4]push ds:[2]pop es:[9*4+2]mov ah,4chint 21hint9: ;更改后的中断服务程序push axin al,60hmov adrs,almov al,20hout 20h,aliretDLY PROC near ;延时子程序PUSH CXPUSH DXMOV DX,10000DL1: MOV CX,9801DL2: LOOP DL2DEC DXJNZ DL1POP DXPOP CXRETDLY ENDPRAND1 PROCPUSH CXPUSH DXPUSH AXSTIMOV AH,0 ;读时钟计数器值INT 1AHMOV AX,DX ;清高6位AND AH,3MOV DL,23 ;除23,产生0~23余数DIV DLMOV frow,AH ;余数存frow,作随机行数POP AXPOP DXPOP CXRETRAND1 ENDPRAND2 PROCPUSH CXPUSH DXPUSH AXSTIMOV AH,0 ;读时钟计数器值INT 1AHMOV AX,DX ;清高6位AND AH,3MOV DL,79 ;除79,产生0~79余数DIV DLMOV fcol,AH ;余数存fcol,作随机列数POP AXPOP DXPOP CXRETRAND2 ENDPCODE ENDSEND start。
贪吃蛇代码

贪吃蛇代码预处理#include#include#include#pragma comment(lib,"Winmm.lib")#define width_window 500 //窗口的宽度#define high_window 398 //窗口的高度#define width_gameBoard 398 //游戏区域的宽度#define high_gameBoard 398 //游戏区域的高度#define sw 10 //用一个圆表示蛇的一节,sw表示圆的半径#define num_food 16 //设定的食物个数,全部吃完则游戏胜利结束#define NameMaxLength 12 //设定用户名的最大字符数为:NameMaxLength-2#define PsdMaxLength 10 //设定密码的最大字符数#define boxbkclr 0xfedcbd //绘制消息框和登录框的主题填充颜色#define drawFieldbkclr 0xFFFFFF //窗口区域的背景填充颜色#define MovDist 1 //按钮移动量为MovDist像素void InitGameBoard(); //创建绘图窗口,并初始化void InitSnake(int x0,int y0,int d0); //用随机数产生蛇的位置和方向void SetFood(); //随机地在蛇以外的位置放置食物int GetPlayerCommand(); //获取游戏玩家发出的控制指令void dispScore(); //动态显示得分void dispInfo(); //显示得分、操作指南和版本等信息void bkMusic_launchImg(); //播放背景音乐和添加启动画面void window_segmented(); //画线分割窗口void GameOver(bool iskillde); //判断游戏是否结束void ClearTailNode(); //擦除蛇尾结点void Eat(int x,int y); //吃食物void SnakeMove(int x,int y,int d); //蛇按照玩家的控制命令进行移动void pause(); //游戏暂停void DrawMsgBox(); //绘制消息窗口int ResponseMouse(int,int,int,int,int,int,int,int,int,int,int,int);//响应鼠标void DrawTwoBtn(); //绘制启动画面上的两个按钮void DrawLoginUI(); //绘制登陆界面void InputName(); //输入账号void InputPsd(); //输入密码int ChkNamePsd(char*,char*); //点击登陆,核对用户名和密码//绘制按钮被点击时有被按压下去并回弹的动感void BthMoveClicked(int,int,int,int,int,int,char*);typedef struct snake{int x;int y;struct snake*next;}SNAKE;SNAKE*head=(snake*)malloc(sizeof(snake));int n=0; //初始化放置食物的个数为0int sx=0,sy=0,sd=0; //蛇头的位置坐标和移动方向int xb00=0,xb01=0,xb02=0,xb03=0,xb04=0,xb05=0;//控件(按钮或输入框)的位置坐标int yb00=0,yb01=0,yb02=0,yb03=0,yb04=0,yb05=0;//控件(按钮或输入框)的位置坐标char UserName[5]={'m','a','r','r','y'}; //系统设定的用户名char Password[6]={'t','o','m','1','2','3'}; //系统设定的密码//用于储存用户输入的账号char IptName[NameMaxLength]={'','','','','','','','\0'};//用于储存用户输入的密码char IptPsd[PsdMaxLength]={'','','','','','','','\0'};int isagin=0; //用于判断是否再玩一次,为1表示再玩一次系统主函数void main(){char str_again[]="再来一次"char str_exit[]="我不玩了"while(1){n=0;//每局开始需要初始化放置食物的个数为0InitGameBoard();//创建绘图窗口,并初始化InitSnake(sx,sy,sd);//用随机数的方式在某个位置产生蛇和蛇的移动方向SetFood();//随机地在蛇以外的位置放置食物SnakeMove(sx,sy,sd);//蛇按照玩家的指控命令进行移动DrawMsgBox();//绘制消息窗口isagain=ResponseMouse(xb00,yb00,xb01,yb01,xb02,yb02,x b03,yb03,0,0,0,0);//响应鼠标点击if(isagain==1)//点击了按钮1“再来一次”{BtnMoveClicked(xb00,yb00,xb01,yb01,6,6,str_again);//绘制动态按钮}if(isagain==2)//点击了按钮1“我不玩了”{BtnMoveClicked(xb02,yb02,xb03,yb03,6,6,str_exit);//绘制动态按钮break;}}closegraph();}1、播放背景音乐和添加启动画面void bkMusic_launchImg(){//播放背景音乐mciSendString("open./千年等一回.mp3 alias 千年等一回",0,0,0);mciSendString("play 千年等一回 repeat",0,0,0);//添加启动画面cleardevice();//用当前背景色清空屏幕,并将当前点移至(0,0)IMAGE img;loadimage(&img, _T("SnakesLaunch1.bmp"));//加载图像putimage(0,0,&img);//显示图像作为启动画面}2、划线分割窗口void window_segmented(){setlinecolor(BLUE);setlinestyle(PS_SOLID|PS_ENDCAP_FLAT,6);//设置线条宽度6的实线,平端点setfillcolor(YELLOW);//划线分割窗口line(width_gameBoard+1,0,width_gameBoard+1,high_game Board);line(width_gameBoard+1,200,width_window,200);//划线分割窗口setlinestyle(PS_SOLID|PS_ENDCAP_FLAT,1);//恢复线条样式为宽度1的实线}3、创建绘图窗口,并初始化void InitGameBoard(){int choice;//点击了哪个按钮int ret=-1;//用于表示核对用户名密码是否正确char str_guide[]="操作指南";char str_regist[]="登录游戏"initgraph(width_window,high_window);//创建大小为width_window*high_window的窗口setorigin(0,0);//设置绘图窗口区域的左上角为逻辑坐标原点setbkcolor(0xFFFFFF);//设置背景颜色,0xFFFFFF为白色bkMusic_launchImg();//播放背景音乐和添加启动画面if(isagain!=1)//是否是重新开始一局{DrawTwoBtn();//绘制启动画面上的两个按钮choice=ResponseMouse(xb00,yb00,xb01,yb01,xb02,yb02,xb 03,yb03,0,0,0,0);if(choice==1)//点击了“操作指南”{BtnMoveClicked(xb00,yb00,xb01,yb01,6,6,str_guide);//绘制动感按钮Sleep(200);//加载并显示操作指南图片IMAGE img;loadimage(&img,_T("SnakesLaunch2.bmp"));putimage(0,0,&img);choice=ResponseMouse(-1,-1,-1,-1,-1,-1,-1,-1,0,0,0,0);if(choice==0)//点击了鼠标左键{//设置绘图样式setlinecolor(WHITE); //设置线条颜色为白色setlinestyle(PS_SOLID|PS_ENDCAP_FLAT,1); //设置线条样式setfillcolor(YELLOW);}}else//点击了“登录游戏”{BtnMoveClicked(xb02,yb02,xb03,yb03,6,6,str_regist);Sleep(200);}DrawLoginUI();//绘制登陆界面window_segmented();//划线分割窗口while(1){if(ret==0)//判断是否已经发生过输入用户名或密码错误{//设置字体颜色为框体填充颜色,目的是擦掉提示错误的信息setcolor(boxbkclr);//设置输入文本的背景颜色为框体填充颜色,目的是擦掉提示错误的信息setbkcolor(boxbkclr);setbkmode(TRANSPARENT);//设置文字输出时的背景模式为透明色settexstyle(18,0,_T("宋体"));//用框体填充颜色输出错误信息,即擦除outtextxy(xb00-50,yb00-20,"账号或密码输入错误,请重新输入!");setbkcolor(drawFieldbkclr);choice=ResponseMouse(xb00,yb00,xb01,yb01,xb02,yb02,xb 03,yb03,xb04,yb04,xb05,yb05);}choice=ResponseMouse(xb00,yb00,xb01,yb01,xb02,yb02,xb 03,yb03,xb04,yb04,xb05,yb05);if(choice==1){InputName();//输入账号}if(choice==2){InputPsd();//输入密码}if(choice==3){ret=ChkNamePsd(IptName,IptPsd);//点击登录if(ret==1)break;}}}cleardevice();//用当前背景色清空屏幕,并将当前点移至(0,0)window_segmented();//划线分割窗口dispInfo();//显示得分和操作指南信息}4、显示得分、操作指南和版本等信息void dispInfo(){//显示得分情况setcolor(BLACK);//设置字体颜色settextstyle(18,0,_T("黑体"));//设置字体类型outtextxy(width_gameBoard+10,30,"当前得分:"); settextstyle(38,0,_T("黑体"));//设置字体类型outtextxy(width_gameBoard+10,60,"0");//显示操作指南信息settextstyle(18,0,_T("黑体"));//设置字体类型outtextxy(width_gameBoard+10,220,"操作指南"); settextstyle(12,0,_T("宋体"));//设置字体类型outtextxy(width_gameBoard+10,250,"按F或f键向东转");outtextxy(width_gameBoard+10,265,"按S或s键向西转"); outtextxy(width_gameBoard+10,280,"按D或d键向南转"); outtextxy(width_gameBoard+10,295,"按E或e键向北转"); outtextxy(width_gameBoard+10,320,"按A或a键向东转"); outtextxy(width_gameBoard+10,335,"按空格键暂停"); outtextxy(width_gameBoard+10,350,"按ESC键退出");//显示版本信息outtextxy(width_gameBoard+10,380,"**贪吃蛇V1.0.0"); }5、动态显示得分void dispScore(){char str_score[6];int num_score=0;num_score=(n-1)*10;//每吃一个得10分itoa(num_score,str_score,10);//数字转化为字符setcolor(RED);setbkmode(OPAQUE);settextstyle(38,0,_T("黑体"));outtextxy(width_gameBoard+10,60,str_score);//显示得分}6、用随机数的方式在某个位置产生蛇和蛇的移动方向void InitSnake(int x0,int y0,int d0){int x,y,d;//蛇的初始位置(x,y)和蛇的移动方向d//用伪随机数产生蛇的初始位置(x,y)和物体的移动方向d//注意:(x,y)不要太靠近四个边,否则可能会出现游戏刚开始就结束了的情况。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Android ----snake源码分析代码结构分析:Snake :主游戏窗口SnakeView:游戏视图类,是实现游戏的主体类TileView :一个处理图片或其它Coordinate :这是一个包括两个参数,用于记录X轴和Y轴简单类,其中包括一个比较函数.RefshHandler :用于更新视图Snake这个类是游戏的主游戏窗口,是框架容器。
1.游戏的开始:oncreate此外的亮点是:setContentView(yout.snake_layout);设置窗口的布局文件,这里Android123给大家说明的是,这里的snake_layout使用了自定义资源标签的方式,大家注意学习:这里我们可以看到来自SnakeView这个派生类的名称,由于Android内部的R.资源不包含SnakeView类,所以我们必须写清楚Package,比如com.exmple.android.snake.SnakeView 然后和其他控件使用一样,都是一个id然后宽度、高度、以及自定义的标签tileSize(尾巴长度),如下:<com.example.android.snake.SnakeViewandroid:id="@+id/snake"android:layout_width="fill_parent"android:layout_height="fill_parent"tileSize="12"/>2.onPause:关于这点,大家可以参考下在我blog中关于active生命周期/admin/blogs/379826在玩游戏过程中,如果有来电或是其它事件中断,这时应该把当前状态保存。
以便返回时,还可以继续玩游戏。
这就使用onSaveInstanceState实现保存当前状态。
TileView注:此部分解析来自: Android示例程序Snake贪食蛇代码分析(三)TileView,从名称上不难看出这是一个方砖类,就是生成一个方块。
TileView使用了Android平台的显示基类View,View类是直接从ng.Object派生出来的,是各种控件比如 TextView、EditView的基类,当然包括我们的窗口Activity类,这些在SDK文档中都说的比较清楚。
这里定义了 5个int型全局的变量,分别是方砖的数量mTileSize;方砖水平x防线的数量mXTileCount;以及竖直y方向上的方砖数量 mYTileCount,下面是一个相对偏移位置mXOffset和mYOffset;这里android123主让要大家了解如何自定义View在 Android开发中,在一个View类中主要是重写onSizeChanged方法来控制改变部分,以及onDraw 实现画布的修改,实现的简写如下:@Overrideprotected void onSizeChanged(int w, int h, int oldw, int oldh) {} @Overridepublic void onDraw(Canvas canvas) { super.onDraw(canvas);} 我们自定义的TileView类需要自己添加一个构造方法,根据需要,我们还重载了一种包含样式的方法,这里大家可以多看下Gallery控件的实现,就好理解了,下面是基本框架。
public TileView(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);}public TileView(Context context, AttributeSet attrs) { super(context, attrs);}在贪食蛇游戏中我们知道Snake是移动的,所以加入了一个清除显示的clearTiles方法,通过一个二维数组保存一个gird网格型的运动轨迹,下一次我们将会讲解android贪食蛇的游戏逻辑和完整的关联拼接实现。
SnakeView在这个类中实现的游戏的实体,从游戏需求的角色,这个游戏包括了如下方面:1.随机产生小苹果,apples这里是复数,当然是是大于1个苹果,所以代码中产生了两个苹果。
2.游戏状态管理3.画蛇,view的更新4.吃掉苹果后小蛇状态的变化5.画围墙如果实现吃掉苹果小蛇速度变快?关键是:mMoveDelay这个变量,以下是涉及到这个变量的函数,每次吃掉苹果后,就会updateSnake一下,里面就把时间处理了:mMoveDelay *= 0.9;小蛇其实就是一个数组,google的代码就是好注释写的清楚:/***mSnakeTrail:a list of Coordinates that make up the snake's body *mAppleList:the secret location of the juicy apples the snake craves.*/private ArrayList<Coordinate> mSnakeTrail= new ArrayList<Coordinate>(); private ArrayList<Coordinate> mAppleList= new ArrayList<Coordinate>();mSnakeTrail:一个由Coordinates列表组织的蛇身.mAppleList:存放鲜美多汁的苹果列表通过这个数组画出小蛇不难,问题是如何判断游戏是否结束?问题是如何判断游戏的状态所有以下的代码来自updateSnake1.吃了苹果// Look for applesint applecount = mAppleList.size();for (int appleindex = 0; appleindex < applecount; appleindex++) {Coordinate c = mAppleList.get(appleindex);if (c.equals(newHead)) {mAppleList.remove(c);addRandomApple();mScore++;mMoveDelay *= 0.9;growSnake = true;}}2.碰到了自己// Look for collisions with itselfint snakelength = mSnakeTrail.size();for(int snakeindex = 0; snakeindex < snakelength; snakeindex++) {Coordinate c = mSnakeTrail.get(snakeindex);if (c.equals(newHead)) {setMode(LOSE);return;}}3.碰到墙了// Collision detection// For now we have a 1-square wall around the entire arenaif ((newHead.x < 1) || (newHead.y < 1) || (newHead.x > mXTileCount - 2) || (newHead.y > mYTileCount - 2)) {setMode(LOSE);return;}源代码分析Snake状态分析:在snakeView中定义了snake游戏的几种状态:private int mMode = READY;public static final int PAUSE = 0; //暂定public static final int READY = 1; //准备好了public static final int RUNNING = 2;//正在运行public static final int LOSE = 3; //结束,输了游戏各种游戏状态rady runningpaused lose 以上状态是通过:void setMode(int newMode)函数实现。
如何实现画出小方块:参看:/blog/206706public class DrawView extends View {private final int mTileSize = 12;private final String TAG="DEMO";private Paint pa = new Paint();private Bitmap mTileArray;void loadImage(){Resources r = this.getContext().getResources();Drawable tile = r.getDrawable(R.drawable.redstar);Bitmap bitmap = Bitmap.createBitmap(mTileSize, mTileSize, Bitmap.Config.ARGB_8888);Canvas canvas = new Canvas(bitmap);tile.setBounds(0, 0, mTileSize, mTileSize);tile.draw(canvas);mTileArray = bitmap;}public DrawView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle);// TODO Auto-generated constructor stubloadImage();x = 10;y = 10;Log.i(TAG, "DrawView 2");}//如果没有这段代码,大家可以试一下,改用上面的代码,程序能否通过。
public DrawView(Context context, AttributeSet attrs) {super(context, attrs);// TODO Auto-generated constructor stubloadImage();Log.i(TAG, "DrawView 3");}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);Log.i(TAG, "onDraw 1");canvas.drawBitmap(mTileArray, x, y, pa);}}通过上面的文章可以画出小方块,但注意到SnakeView一共有两构造函数,那个函数才真正起作用呢?●public SnakeView(Context context, AttributeSet attrs)●public SnakeView(Context context, AttributeSet attrs, int defStyle)通过加log的方式,判断是第一个构造函数起作用。