用html5 canvas和JS写个数独游戏
为啥要写这个游戏?
- 因为我儿子二年级数字下册最后一章讲到了数独。他想玩儿。
- 因为我也想玩有提示功能的数独。
- 因为我也正想决定要把HTML5和JS搞搞熟。熟悉一个编程平台,最好的办法,就是了解其原理与思想之后,做个真正完整的东西练练。
之前一直搞.net,后来管理事务多了,很多技术就没跟上,看过一些JS的书,但一直没动手,前几个月,写了第一个JS程序,是一个简单的产品规则引擎,利用v8引擎集成在.net程序中,用脚本来处理产品费用有关的计算。但那个只涉及数值计算。
这几天因为儿子的课本上学逻辑推理,有个数独游戏,儿子大感兴趣,玩了几个,想到如果能自动计算可选数字的话,就会很容易解开数独,在网上找来找去,发现都没有这样功能的数独。正好有点空闲,就决定自已写一个。
所以这个数独是我写的第二个JS程序。在写的过程中也在同时学习。
几个要点
canvas与windows的图形程序原理的不同
一开始,免不了受之前经验的影响,想用winform的图形程序原理来处理html5 canvas的绘图。但发现有点水土不服:windows的图形程序原理是说系统不管保存程序自己窗口里内容,有需要显示时——比如从后台切到前台啦、刚从别的程序下面露出脸来啦等等——就请程序自己再画一遍。所以,程序只需要重写form的OnPaint方法(对于win32程序,则是响应WM_PAINT消息),在其中绘制图形就行了。
在windows程序中,不能直接随时向窗口上画图,比如你想在鼠标点击时画个点,但你没法在鼠标或键盘事件的响应方法中得到窗口的绘图上下文句柄(对winform,是Graphics参数,对于win32程序是WM_PAINT消息里的某个参数),于是,你只好记下来“现在有个家伙点了鼠标了,某某地方应该有个点!”,然后调用Invalidate()方法,这个方法会强制系统向窗口程序发重绘消息,然后,你事先准备好的OnPaint方法被调用,在这个方法里,你有机会得到绘图句柄了,于是你检查之前有没有记录过要在某个地方画点的,并在这个地方画个点。
有点像MVC的意思,哈?
但在html5的canvas中,我发现浏览器是会帮canvas保存图形的,无论是被其他窗口盖到,切到后台,都没问题,只要一露出到屏幕上,原来的图形就还是在那里。这表示只要你并不想做动画效果,用canvas写图形程序要比windows程序原理更简单一些:你只要在合适的时候(鼠标点击、键盘事件等)向canvas上画图就是了,画上的东西就会总是在那里。绘图上下文context也不会消失掉,我把它在一开始时做为构造方法的参数传入,并保存为类成员,随时用随时取。
唯一要注意的,是要快点画完,别占太长时间。
滚屏后座标的问题
从网上看到的代码都是用e.pageXY来得到位置的。这个位置是鼠标事件在整个文档中的绝对位置。也就是说,滚屏不会影响这个值。
只不过我用了getBoundingClientRect这个方法来取得canvas对应的box座标,用于把全局座标转换到canvas内的座标。而这个方法取得的座标是相对于浏览窗口的,而不是相对于整个文档的。这就与e.PageXY对不上了。
所以,这里只好用e.XY,工作得非常好。
支持Retina屏
一开始在一个旧笔记本上写的这个程序,运行得挺好,但放到MacBook Pro上一看,功能挺正常,但内容很模糊。
仲么办!
模糊的原理是canvas在浏览器中的大小是由style中的width与height来决定的,但其画布的大小是以canvas.width与height决定的。如果两者不一样大,就会进行拉伸缩放,把画布拉伸(或缩小)到style的大小。
在普通屏幕上,其style定义的像素大小与屏上的显示结果是一对一的,所以没问题。但在retina屏上,style的大小定义与屏幕上的像素大小是有个放大比例的(在MBP上,是2),也就是说,style定义的400px,显示时会用到800px个屏幕像素。但由于canvas里画布的大小是400px的,所以内容被拉伸,还自动消除了锯齿,看起来就很模糊。
所以,解决办法是就是:根据放大比例,把画布的大小设置为比外部大小更大的大小。
但是注意,鼠标器事件中的座标是按原点数值来提供的。比如说,你内部画布大小是800px, 但屏幕大小算成了400px, 当鼠标点击后,给的位置是(100,100),这个位置是按屏幕点数来计算的,要在画布中计算其对应的点,应该把这个值乘以那个放大系数才对。
可注意一下程序中的getPointOnCanvas函数。
源代码在: https://github.com/haoxiaobo/SudoJS
用html5 canvas和JS写个数独游戏的更多相关文章
- 基于html5 canvas和js实现的水果忍者网页版
今天爱编程小编给大家分享一款基于html5 canvas和js实现的水果忍者网页版. <水果忍者>是一款非常受喜欢的手机游戏,刚看到新闻说<水果忍者>四周年新版要上线了.网页版 ...
- HTML5 Canvas核心技术:图形、动画与游戏开发 PDF扫描版
HTML5 Canvas核心技术:图形.动画与游戏开发 内容简介: <HTML5 Canvas核心技术:图形.动画与游戏开发>中,畅销书作家David Geary(基瑞)先生以实用的范例程 ...
- 用 JS 做一个数独游戏(二)
用 JS 做一个数独游戏(二) 在 上一篇博客 中,我们通过 Node 运行了我们的 JavaScript 代码,在控制台中打印出来生成好的数独终盘.为了让我们的数独游戏能有良好的体验,这篇博客将会为 ...
- 用 JS 做一个数独游戏(一)
用 JS 做一个数独游戏(一) 数独的棋盘由 9x9 的方格组成,每一行的数字包含 1 ~ 9 九个数字,并且每一列包含 1 ~ 9 这 9 个不重复的数字,另外,整个棋盘分为 9 个 3x3 的块, ...
- canvas原生js写的贪吃蛇
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- html5+Canvas实现酷炫的小游戏
最近除了做业务,也在尝试学习h5和移动端,在这个过程中,学到了很多,利用h5和canvas做了一个爱心鱼的小游戏.点这里去玩一下 PS: 貌似有点闪屏,亲测多刷新两下就好了==.代码在本地跑都不会闪, ...
- HTML5 Canvas核心技术—图形、动画与游戏开发.pdf1
canvas元素可以说是HTML5元素中功能最强大的一个,它真正的能力是通过Canvas的context对象(绘图上下文)表现出来的 fillText()方法使用fillStyle属性来填充文本中的字 ...
- HTML5 Canvas核心技术—图形、动画与游戏开发.pdf7
性能 运行putImageData()比drawImage()慢,同等条件下优先考虑drawImage() 操作图像数据需要遍历大量数据,应该注意几点: 1)避免在循环体中直接访问对象属性,应当保存在 ...
- HTML5 Canvas核心技术—图形、动画与游戏开发.pdf6
操作图像的像素:getImageData() putImageData() ImageData对象 调用getImageData()方法实际是获取了一个指向ImageData对象的引用,返回的对象包含 ...
随机推荐
- VS2013新建MVC5项目,使用nuget更新项目引用后发生Newtonsoft.Json引用冲突的解决办法
错误信息如下: 错误 3 类型“Newtonsoft.Json.JsonPropertyAttribute”同时存在于“c:\Program Files (x86)\Microsoft V ...
- 浅谈Bluetooth蓝牙开发
前言:项目用到蓝牙开发,具体蓝牙获取硬件传感器中的数据. 因为没有蓝牙开发的相关经验,决定先了解一些蓝牙开发的知识,再去看之前同事写的蓝牙相关代码. ------------------------- ...
- Linux常用命令:sed
本文记录的是自己在学习<Linux私房菜>中正则表达式的笔记. 关于行尾符$ 如果文件本身没有内容,比如使用touch新建的文件,那么$将会没有意义.例如下面操作: 先使用touch新建了 ...
- Android 学习心得 快速排序
快速排序(Quicksort) 是对冒泡排序的一种改进,它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分 ...
- Android中Listview点击item不变颜色以及设置listselector 无效
Android中Listview点击item不变颜色以及设置listselector 无效 这是同一个问题,Listview中点击item是会变颜色的,因为listview设置了默认的listsele ...
- C#委托的介绍(delegate、Action、Func、predicate) --转载
来源:http://www.cnblogs.com/akwwl/p/3232679.html 委托是一个类,它定义了方法的类型,使得可以将方法当作另一个方法的参数来进行传递.事件是一种特殊的委托. 1 ...
- php环境搭建wampserver、Apache、Mysql和php
wampserver2.5-Apache-2.4.9-Mysql-5.6.17-php5.5.12-32b搭建php环境 在win下,下载wampserver2.5-Apache-2.4.9-Mysq ...
- 您不能在64位可执行文件上设置DEP属性
原因:32位的跟64位不匹配 解决方案: 更改文件目录为:C:\\Windows\SysWOW64dll\host.exe
- ubuntu中chromium无法播放flash,安装flash
ubuntu14.0.4中系统自带的chromium无法播放flash,后来查了下,得知chromium已经不支持adobe flash了,用户可使用pepper flash替代.安装pepper f ...
- Linux 负载监控脚本
#!/bin/bash Date=`echo $(date +%Y\-%m\-%d\ %H:%M:%S)`HostName=`hostname`IP=`ifconfig eth0 | grep &qu ...