html5,制作游戏,如何实现键盘操作人物html平滑滚动移动

Android游戏开发实践之人物移动地图的平滑滚动处理
玩过rpg游戏的朋友应该都知道RPG的游戏地图一般都比较大 今天我和大家分享一下在RPG游戏中如何来处理超出手机屏幕大小的游戏地图。
如图所示为程序效果动画图
地图滚动的原理
在本人之前博客的文章中介绍过人物在屏幕中的移动方式,因为之前拼的游戏地图是完全填充整个手机屏幕的,所以无需处理地图的平滑滚动。这篇文章我着重的向 大家介绍一下控制人物移动后地图滚动的处理方式。举个例子 如上图所示 比如人物向右移动,如果地图贴在屏幕左边边界 将先移动人物在地图的坐标,当人物在屏幕中超过三分之二后 则将地图向人物行走的反方向移动给玩家一种人物还在向右移动的假象,其实这时候人物只是播放向右行走的动画 在屏幕中的坐标不变 ,当地图向人物行走反方向移动到不能移动的时候 则表示 地图右侧边界已经贴住手机屏幕右侧边界 这样地图则不能在移动 这时候将移动人物在屏幕上的坐标直到人物贴住屏幕右侧边界,其它三个方向原理完全一样。
代码的实现方式
还是以人物向右移动为例,我们须要三个坐标 一个是m_HeroPos 来保存人物在地图中的X坐标 一个是 mScreenPos 来保存人物在屏幕中的显示坐标 mMapPos 来保存地图在手机屏幕中的显示坐标,按键盘右键后人物在地图中的坐标加上8像素(表示行走的步长),当人物的坐标超过屏幕的三分之二的时候需要检测地图是 否已经在边界, 使用地图绘制在屏幕中的X坐标 加上地图的宽度 判断是否等于屏幕的宽度如果等式不成立 则表示地图可以向左放移动 这时候后人物mScreenPos人物显示坐标将不变 mMapPos地图显示坐标将向左移动人物一个步长的位置,如果之前的等式成立 则表示地图无法在向左移动 这时候mScreenPos人物显示坐标将向右移动人物一个步长的位置 直到屏幕右侧边界 mMapPos地图显示坐标不会改变。其三个方向的移动算法完全一样。
如图所示地图在平滑的滚动
拓展学习之卡马特地图缓冲算法
这个游戏demo 还不能称之为完美 在与物理层碰撞中还是存在一点问题 不过 最重要的是 没有使用卡马克地图缓冲算法, 下面我详细介绍一个卡马克地图缓冲算法原理。我们需要一张地图换冲图, 为了实现平滑滚动的效果缓冲图的大小应该是手机屏幕宽高 ,这样内存中就会常驻 一张 手机屏幕大小的缓冲图。 如果人物向下方行走则表示地图向上移动,这时候屏幕 将被切割出来了2部分, 上半部分为缓冲图向上移动后的缓冲内容,下半部分则就是我们需要更新地图的部分,将更新后的下半部分与地图缓冲的上半部分结合起来绘制在屏幕中则完成了一 次地图更新,这样可以大大提升游戏绘制地图的效率。如果不使用这种方式来更新地图 则地图每移动一次 都须要双for循环重新一个tile一个tile的绘制一遍效率会很低下。
如图所示 地图向上移动后更新绿色的地图部分 与 将上次缓冲的红色部分结合起来就是新的游戏地图,其它方向原理完全一样。
如图所示:如果游戏中可以按右下方式来移动主角 那么以屏幕右下角为圆心 地图就会被切割成4个部分下图中红色区域须要更新其中 3 个部分 地图左边超出的部分 地图下面超出的部分 地图左下方超出的部分,更新的原理和上面一样。
这么看来卡马克不愧是个游戏领域的天才,马克地图缓冲算法不愧是最最优秀的地图算法之一,大家如有有兴趣可以去查一查关于卡马特的资料,他确实是一个顶尖的游戏开发工程师。
Copyright (C) , All Rights Reserved.
版权所有 闽ICP备号
processed in 0.037 (s). 13 q(s)博客分类:
我用到的图片-
package dk.
import android.app.A
import android.os.B
import android.view.W
import android.view.WindowM
public class MainActivity extends Activity {
/** Called when the activity is first created. */
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//去掉标题
requestWindowFeature(Window.FEATURE_NO_TITLE);
//全屏显示
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(new GameView(this));
package dk.
import android.content.C
import android.graphics.B
import android.graphics.BitmapF
import android.graphics.C
import android.graphics.C
import android.graphics.P
import android.graphics.R
import android.util.L
import android.view.KeyE
import android.view.SurfaceH
import android.view.SurfaceV
public class GameView extends SurfaceView implements Runnable,SurfaceHolder.Callback {
//刷屏主线程
private Thread gameT
//游戏屏幕宽和高
public static int screen_width,screen_
private SurfaceH
private boolean run_flag=
//敌人图片
private Bitmap bmp_
//移动速度
private int enemy_speed=5;
//角色移动控制帧
private int frame=0;
//按键上下左右移动的判断
private boolean is_up,is_down,is_left,is_
//上下左右移动动画帧编号
private int[] enemy_up={3,4,5};
private int[] enemy_down={0,1,2};
private int[] enemy_left={6,7,8};
private int[] enemy_right={9,10,11};
//当前帧动画
private int[] enemy_start=enemy_
//初始角色单帧图片右上角位置和单帧图片宽和高
//右上角位置作为图片的人物的控制点不太合适
//private int X=50,Y=50,W,H;
//人物的控制点坐标和宽高
private int X,Y,W,H;
public GameView(Context context) {
super(context);
sfh=getHolder();
sfh.addCallback(this);
paint =new Paint();
paint.setAntiAlias(true);
//获得焦点
setFocusable(true);
setClickable(true);
setFocusableInTouchMode(true);
//保持屏幕常亮
setKeepScreenOn(true);
bmp_enemy=BitmapFactory.decodeResource(getResources(), R.drawable.enemy);
W=bmp_enemy.getWidth()/13;
H=bmp_enemy.getHeight();
//这里我以单帧图片的中心点为控制点。具体控制点的位置,主要看你的图片了
public void draw(Canvas canvas,Paint paint){
第一种绘制方法
canvas.drawColor(Color.GRAY);
//屏幕显示区域
Rect rect_dst=new Rect(X-W/2, Y-H/2, X+W/2, Y+H/2);
//图片截取区域
Rect rect_src=new Rect(enemy_start[frame]*W, 0, (enemy_start[frame]+1)*W, H);
canvas.drawBitmap(bmp_enemy,rect_src,rect_dst,paint);
第二种绘制方法
canvas.save();
canvas.drawColor(Color.GRAY);
//设置可视区域
canvas.clipRect(X-W/2, Y-H/2, X+W/2, Y+H/2);
canvas.drawBitmap(bmp_enemy,X-enemy_start[frame]*W-W/2,Y-H/2,paint);
canvas.restore();
public void logic(){
//根据按键状态判断
if(is_up){
}else if(is_down){
}else if(is_left){
}else if(is_right){
//边界暂时先不判断
if(X&screen_width){
if(Y&screen_height){
//移动动画帧的处理
if((is_up || is_down||is_left ||is_right)|| frame!=0){
if(frame&2){
public boolean onKeyDown(int keyCode, KeyEvent event) {
if(keyCode==KeyEvent.KEYCODE_DPAD_UP){
enemy_start=enemy_
}else if(keyCode==KeyEvent.KEYCODE_DPAD_DOWN){
enemy_start=enemy_
}else if(keyCode==KeyEvent.KEYCODE_DPAD_LEFT){
enemy_start=enemy_
}else if(keyCode==KeyEvent.KEYCODE_DPAD_RIGHT){
enemy_start=enemy_
return super.onKeyDown(keyCode, event);
public boolean onKeyUp(int keyCode, KeyEvent event) {
return super.onKeyUp(keyCode, event);
public void run() {
while (run_flag) {
long startTime=System.currentTimeMillis();
canvas=sfh.lockCanvas();
draw(canvas, paint);
long endTime=System.currentTimeMillis();
long useTime=endTime-startT
//固定屏幕刷新的时间为50ms
if(useTime&50){
Thread.sleep(50-useTime);
} catch (Exception e) {
Log.e("Error", "刷屏线程出错了"+e);
if(canvas!=null){
sfh.unlockCanvasAndPost(canvas);
public void surfaceCreated(SurfaceHolder holder) {
screen_width=getWidth();
screen_height=getHeight();
gameThread=new Thread(this);
//启动线程
gameThread.start();
public void surfaceDestroyed(SurfaceHolder holder) {
gameThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
public void surfaceChanged(SurfaceHolder holder, int format, int width,int height) {}
最后源码下载
http://dl.iteye.com/topics/download/-97b2-3bd9-a7b7-b5
下载次数: 233
浏览: 170411 次
来自: 郑州
顶下楼主,新学。
jay_st 写道能解释下这两个MAIN的用意吗,?你单独运行 ...
能解释下这两个MAIN的用意吗,?
jay_st 写道看过了,不错,但是为什么里面有两个MAIN那 ...
看过了,不错,但是为什么里面有两个MAIN
(window.slotbydup=window.slotbydup || []).push({
id: '4773203',
container: s,
size: '200,200',
display: 'inlay-fix'如何编程实现在图片上平滑移动文字,详细过程。。。。帮个忙了,谢谢_百度知道
如何编程实现在图片上平滑移动文字,详细过程。。。。帮个忙了,谢谢
VB也可以,但不会用呀,只要能实现什么语言都可以的
我有更好的答案
你要用什么语言啊
在 VB 中,可以使用以下步骤及方法实现此“特技”:   1、新建一工程文件,缺省创建 Form1; 2、在 Form1 上放置 Picture Box 控件 Picture1,选择背景图片; 3、选择 Picture1(即以它为一个容器),在上面放置 Label 控件 Label1,设置 Label1 的 BorderStyle 属性为 0(透明——即在控件后的背景色和任何图片都是可见的),设置 Caption 为待移动的字符串; 4、在 Form1 上放置 Timer 控件 Timer1,设置 Enabled 属性为 True,设置 Interval 为 100,在 Timer1 的 Timer 事件中加入以下程序: iStep=20 Label1.Top=Label1.Top - iStep Interval 决定图形移动速度;iStep 决定图形移动的平滑程度。 5、在 Form_Load 事件中加入以下程序: face=&宋体&&Lable1.Top = Picture1.ScaleHeight   到此,你就可以实现文字在图形上的平滑移动。本例产生的效果是由下向上移动,如果你将程序稍加改变,就可以实现由下到上,由左到右,由右到左等“特技”效果。
就是不会用vb啊,这个答案百度上也有啊
你会用什么语言的??学过什么
学过c++,要求用java或vc或vb,可本人学的不怎样,不知道怎么弄啊
建议采用TPaintBox
控件 在它的OnMouseMove事件里头写 实现用一个Graphics::TBitmap
将源图导入 Graphics::TBitmap
* 假设你已计算好Mouse移动前图象移动后要显示的矩形RectSrc(相对于源图而言) void
__fastcall
TForm1::PaintBox1MouseMove(TObject
TShiftState
if(Shift.Contains(ssLeft)){//当Left
一直按下时
//此处也可用个bool值在Mousedown
SetStretchBltMode(PaintBox1-& Canvas-& Handle,COLORONCOLOR);
StretchBlt(PaintBox1-& Canvas-& Handle,0,0,PaintBox1-& Width,PaintBox1-& Height,
bmp-& Canvas-& Handle,RectSrc.Left,RectSrc.Top,RectSrc.Width(),RectSrc.Height(),SRCCOPY);
//
计算你的RectSrc
呵呵呵,谢谢你哦,我已经会用vb做了,你是学计算机的吗
是学计算机的
呵呵呵,你软件很厉害了啰!你会编人事管理系统吗?结合数据库的!唉~~我们的实训啊,太难了,弄得我头都大了。
采纳率:32%
覃韵哈,呵呵
为您推荐:
其他类似问题
帮个忙的相关知识
换一换
回答问题,赢新手礼包
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。C++编小游戏时怎样实现按键使物体移动啊?_百度知道
C++编小游戏时怎样实现按键使物体移动啊?
我有更好的答案
游戏的制作,至少应该注意一点逻辑与渲染分离也就是说,你的游戏其实和界面没有任何关系比如你要移动一个物体,比如用POINT来记录位置,只需要在键盘事件中改变POINT的值就可以了,其他的就不用做了,然后就是强制刷新,用Invalidate或其他的函数就可以了。在显示函数中,你在根据物体的位置来移动物体。也就是说逻辑就是逻辑,其他的什么也不做,渲染只是根据你当前的物体的各种属性比如位置,进行渲染而已,没有界面一样是游戏,一样可以玩,不过这样的游戏没有人玩而已。
采纳率:23%
增加消息处理OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)然后GetDlgItem(物体的ID)-&setposion(x,y);就行了
你这样说,很难给你说怎样去移动。因为游戏多数是在游戏引擎那里去开发完成。入门级别的有HGE引擎。原理就是if(按键条件){
X++;//X为横坐标}
为您推荐:
其他类似问题
您可能关注的内容
小游戏的相关知识
换一换
回答问题,赢新手礼包
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。欢迎访问我的个人博客:
最近除了做业务,也在尝试学习h5和移动端,在这个过程中,学到了很多,利用h5和canvas做了一个爱心鱼的小游戏。
PS: 貌似有点闪屏,亲测多刷新两下就好了==。代码在本地跑都不会闪,放到博客里就闪了,我也不知道为什么。。。回头我再看看是什么问题。
另外,我把代码放到github上了,博友们也可以直接down代码,不需要任何服务,本地就能跑起来。大家要是觉得还行,就给个star吧!
首先截个图来看看界面效果:
下买我就做游戏的步骤来分享总结一下用到的h5API和一些常见的数学函数。(推荐你先去玩一玩游戏,才能更好的明白这些逻辑哟~)
首先,一个游戏最重要的就是动画,怎么让元素动起来呢?先来看一句话:
元素的位置移动,就形成了动画。
一帧一帧的来渲染这个元素,而且这个元素每一帧的位置都不一样,我们的眼睛看到的就是动画了。OK,先来介绍requestAnimationFrame这个函数。
我们都知道,隔一段时间重新渲染,可以用到setTimeout 和setInterval这两个函数,那这里为什么不用呢?
我来简单举个例子吧:
setInterval(myFun, 1); 意思是隔一毫秒执行一个myFun函数,但是这样就有一个问题了,比如我myFun函数里面绘制的东西比较耗时,而1ms之内还没有完全绘制出来,但是这段代码强制1ms之后又开始绘制下一帧了,所以就会出现丢帧的问题,而如果时间设置太长,就会出现视觉卡顿的问题。
requestAnimationFrame(myFun); 如果我们这样写,又是什么意思呢?意思是根据一定的时间间隔,会自动执行myFun函数来进行绘制。这个“一定的时间间隔”就是根据浏览器的性能或者网速快慢来决定了,总之,它会保证你绘制完这一帧,才会绘制下一帧,保证性能的同时,也保证动画的流畅。
动画解决了,那么用什么来绘制每一帧的页面呢?这时就要用到h5的神奇——canvas了,所以canvas画布的API非常重要。
&div class=&page&&
&div class=&content& id = &main&&
&canvas id = &canvas1& width=&800& height=&600&&
&canvas id = &canvas2& width=&800& height=&600&&
定义两个画布,分别在画布上绘制相应的物体;
canvas2 上绘制,背景、海葵、果实;
canvas1 上绘制,大鱼、小鱼、显示文字、圆圈特效;
function init(){
can1 = document.getElementById('canvas1');
ctx1 = can1.getContext('2d');
can2 = document.getElementById('canvas2');
ctx2 = can2.getContext('2d');
//下面的canvas
function gameloop(){
requestAnimFrame(gameLoop);
//绘制物体...
var requestAnimFrame = (function() {
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame ||
function(callback, element) {
return window.setTimeout(callback, 1000 / 60);
init函数初始化一些变量,比如海葵对象,大鱼、小鱼对象等等。
gameloop函数用于绘制每一帧的页面。下面所介绍的所有绘制函数都是在这里执行。
requestAnimFrame函数是为了兼容所有浏览器。
下面我们就开始绘制游戏中出现的东西,顺便看看都用到了哪些有趣的API函数。go!go!go!
绘制背景和海葵
背景是一张图,而海葵是一个类,它有x坐标,y坐标,个数等等属性,有初始化init和draw方法。
drawImage(image, x, y, width, height)
ctx2.save();
ctx2.globalAlpha = 0.7;
ctx2.lineWidth = 20;
ctx2.lineCap = 'round';
ctx2.strokeStyle = '#3b154e';
ctx2.beginPath();
ctx2.moveTo(this.rootx[i], canHei);
ctx2.lineTo(this.rootx[i], canHei - 220,);
ctx2.stroke();
ctx2.restore();
ctx2.drawImage(image, x, y, width, height) //x,y代表坐标,width和height代表宽高
ctx2.save(); //定义作用空间
ctx2.globalAlpha = 0.7; //定义线的透明度
ctx2.lineWidth = 20; // 宽度
ctx2.lineCap = ‘round’; // 圆角
ctx2.strokeStyle = '#3b154e'; //定义绘制线条的颜色
ctx2.beginPath(); //开始路径
ctx2.moveTo(x,y); //线的起点,x,y代表坐标(坐标原点在左上角)
ctx2.lineTo(x,y); // 线条从起点连接到这个点
ctx2.stroke(); // 开始绘制线条
ctx2.restore(); //作用空间结束
海葵产生果实
果实也是一个类,他的属性有:坐标、类型(黄色和蓝色)、大小、状态(显示还是隐藏)、速度(向上漂浮的速度)等等属性;他的方法有:初始化init、出生born和绘制draw。
draw方法:
for(var i =0;i& this.num; i++){
if(this.alive[i]){
//find an ane, grow, fly up...
if(this.size[i] &= 16){
//长大状态
this.grow[i] = false;
this.size[i] += this.speed[i] * diffframetime * 0.8;
//已经长大,向上漂浮
this.grow[i] = true;
this.y[i] -= this.speed[i] * 5 * diffframetime;
var pic = this.orange;
if(this.type[i] == 'blue')
pic = this.blue;
ctx2.drawImage(pic, this.x[i] - this.size[i] * 0.5, this.y[i] - this.size[i] * 0.5, this.size[i], this.size[i]);
if(this.y[i] & 8){
this.alive[i] = false;
born方法:随机找到一个海葵的坐标,在海葵的坐标上出生一个果实。
绘制大鱼和小鱼
大鱼和小鱼都是一个类,它的属性有:坐标、旋转角度、尾巴摆动时间间隔、眨眼睛时间间隔、身体图片数组....等等
先把大鱼绘制出来,用canvas的drawImage方法。
比较难的是大鱼的动画,大鱼会随着鼠标移动而移动的动画,这里定义了两个函数:
function lerpAngle(a, b, t) {
//计算每一帧旋转的角度
var d = b - a;
if (d & Math.PI) d = d - 2 * Math.PI;
if (d & -Math.PI) d = d + 2 * Math.PI;
return a + d * t;
function lerpDistance(aim, cur, ratio) {
//aim:目标 cur:当前 ratio:百分比
计算每一帧趋近的距离
var delta = cur - aim;
return aim + delta * ratio
this.momTailTimer += diffframetime;
if(this.momTailTimer & 50){
this.momTailIndex = (this.momTailIndex + 1) % 8;
//根据时间间隔改变尾巴图片
this.momTailTimer %= 50;
lerpDistance 是计算每一帧大鱼趋紧到鼠标的距离。
lerpAngle 用来计算大鱼每一帧向鼠标旋转的角度。 定义这两个函数,让大鱼动起来比较平滑。
获得了一个角度之后,怎么让大鱼旋转起来呢?这里又需要用到几个API了。
ctx1.save(); //建议每次绘制都使用save和restore,可以避免定义样式,发生冲突。
ctx1.translate(this.x, this.y); //把原点变成(this.x , this.y);
ctx1.rotate(this.angle); //根据原点顺时针旋转一个角度
绘制小鱼跟大鱼是一样的,不做详述。但是需要注意的是绘制小鱼的时候有个判断,当小鱼的颜色变白的时候,游戏结束。
this.babyBodyTimer += diffframetime;
if(this.babyBodyTimer & 550){
//身体图片变化的计数器 & 550ms
this.babyBodyIndex += 1;
//身体图片变淡
this.babyBodyTimer %= 550;
scoreOb.strength = ((20 - this.babyBodyIndex)/2).toFixed(0);
if(this.babyBodyIndex & 19){
//如果身体变成白色,game over;
this.babyBodyIndex = 19;
scoreOb.gameOver = true;
can1.style.cursor = &pointer&;
大鱼吃果实
大鱼吃果实是根据距离来判断定的,如果大鱼和果实的距离小于30,则让果实消失,并且出现白色圆环,并且分值有一定的变化。
jzk.momEatFruit = function(){
//判断果实和大鱼之间的距离,小于30说明被吃掉
for(var i = 0;i & fruitOb.num; i++ ){
if(fruitOb.alive[i] && fruitOb.grow[i]){
var len = calLength2(fruitOb.x[i], fruitOb.y[i], momOb.x, momOb.y);
if(len & 30){
fruitOb.dead(i);
//如果距离小于30,则被吃掉
waveOb.born(i);
//吃掉的时候,产生圆圈
scoreOb.fruitNum ++;
//吃到的果实数量+1
momOb.momBodyIndex = momOb.momBodyIndex == 7 ? momOb.momBodyIndex : (momOb.momBodyIndex + 1);
//大鱼的身体颜色红
if(fruitOb.type[i] == 'blue'){
scoreOb.doubleNum ++;
//吃到蓝色果实,倍数+1
其中有一个calLength2函数,使用来计算两个点之间的距离的。
function calLength2(x1, y1, x2, y2) {
//计算两个点之间的距离,,, 先求平方和,再开平方
return Math.sqrt(Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2));
大鱼吃到果实的时候,会产生一个白色的圆圈,这个效果怎么实现呢?
首先,我们定义一个waveObject类,它的属性有:坐标、数量、半径、使用状态。它的方法有:初始化、绘制和出生。
我们来看一下绘制圆圈的方法:
for(var i = 0;i& this.num; i++){
if(this.status[i]){
//如果圆圈是使用状态,则绘制圆圈
this.r[i] += diffframetime * 0.04;
if(this.r[i] & 60){
this.status[i] = false;
return false;
var alpha = 1 - this.r[i] / 60;
ctx1.strokeStyle = &rgba(255, 255, 255, &+ alpha +&)&;
ctx1.beginPath();
ctx1.arc(this.x[i], this.y[i], this.r[i], 0, 2 * Math.PI);
ctx1.stroke();
一帧一帧的画每一个圆,圆的半径逐渐增大,透明度逐渐减小,直到半径大于60的时候,把状态设为false,让其回归物体池中。
这里又用到了一个新的方法:ctx1.arc(x,y,r,deg); //画圆,x,y是中心圆点,r是半径,deg是角度,360度就是一个整圆。
再来看一下出生的方法:
for(var i = 0; i& this.num; i++){
if(!this.status[i]){
this.status[i] = true;
//把圆圈状态设为使用状态
this.x[i] = fruitOb.x[index];
this.y[i] = fruitOb.y[index];
this.r[i] = 10;
return false;
//找到一个未使用的圆圈,就结束。
圆圈出生的坐标就是被吃果实的坐标。
大鱼喂小鱼
大鱼喂小鱼同上,不再详述,这里喂小鱼之后,大鱼身体变白,小鱼随果实数量相应增多,另外需要注意的是,此时产生圆圈的坐标是小鱼的坐标。
游戏分值计算
定义一个数据类,它的属性有:吃到的果实数量、倍数、总分、力量值、游戏状态(是否结束)等;方法有:初始化、绘制分数。
这里我们需要在画布上绘制文字,又用到了新的API:
ctx1.save();
ctx1.font = '40px verdana'; 定义文字的大小和字体;
ctx1.shadowBlur = 10; 定义文字的阴影宽度
ctx1.shadowColor = &white&; 定义文字阴影的颜色;
ctx1.fillStyle = &rgba(255, 255, 255, &+ this.alpha +&)&; 定义文字的颜色(rgba,a代表透明度)
ctx1.fillText(&GAME OVER&, canWid * 0.5, canHei * 0.5 - 25); 绘制文字,第一个参数是字符串,支持表达式,后两个参数是坐标值。
ctx1.font = '25px verdana';
ctx1.fillText(&CLICK TO RESTART&, canWid * 0.5, canHei * 0.5 + 25);
ctx1.restore();
好啦,整个游戏的制作过程就分享完了,做的过程中有遇到过很多问题,不过都一一解决了,加深了很多以前模糊的概念,也学到了很多新的知识,比如使用rgba()来一起控制颜色和透明度,以前还真没用到过。
这个游戏本身功能比较简单,但是动画还算比较酷炫。这也算是一个比较基本的动画基础框架了,而比较不容易理解的地方也有很多,比如求趋近的角度函数lerpAngle(a,b,c),还有Math.atan2()这个函数,等等。
欢迎大家提出bug或者改进建议~~~
ps: 本实例是从慕课网上学习到的。然后自己跟着老师从头做了一遍,并且优化了很多代码,新加了一些功能。我觉得只要自己能画出来,就是自己的作品。
阅读(...) 评论()
欢迎访问我的个人博客,效果更佳哟!

我要回帖

更多关于 js实现锚点间平滑滚动 的文章

 

随机推荐