typescript 简版跳一跳

学习typescript,第一步应该是学习官方文档,理解最基础的语法。第二步开始用typescript实现一些js+css 或者canvas类型的游行。现在开始我们用ts写跳一跳

核心点:1.场景的随机创建

    2.旗子的跳动

    3.落脚点的判断,重点要提及的是射线判断法,参见博客

    4.场景平移

    5.游戏重置

    6.销毁场景外方块

Ts代码:

 //1.创建底座:
//2.创建跳棋:
//3.点击移动
//4.开始按压动画,
//5.放开动画
//6.跳动
//7.是否跳对
//8.移动场景
//9.创建新底座
module Jump {
interface Pos {
x: number;
y: number;
}
enum Flag {
on, in, out
}
enum Direction {
left,
right
}
let direction: Direction = Direction.right;
let diamondsList: diamonds[] = [];
let mask: JQuery<HTMLElement> = $(".game-p");
let chess: Chess;
let score:number=0;
class MathHelp {
/**
* 返回范围内随机数[min,max]
* @param min 最小值
* @param max 最大值
*/
static RandRange(min: number, max: number): number {
return Math.floor(Math.random() * (max - min + 1) + min);
}
/**
* 根据角度求对边长度。Math.sin(randian)
* @param r 斜边长
* @param angle 角度
*/
static righttriangle(r: number, angle: number): number {
return Math.sin(Math.PI / 180 * angle) * r;
}
/**
* 射线法判断点是否在多边形内部
* @param p 待判断的点
* @param poly 多边形顶点
*/
static rayCasting(p: Pos, poly: Pos[]): Flag {
var px = p.x,
py = p.y,
flag = false for (var i = 0, l = poly.length, j = l - 1; i < l; j = i, i++) {
var sx = poly[i].x,
sy = poly[i].y,
tx = poly[j].x,
ty = poly[j].y // 点与多边形顶点重合
if ((sx === px && sy === py) || (tx === px && ty === py)) {
return Flag.on;
} // 判断线段两端点是否在射线两侧
if ((sy < py && ty >= py) || (sy >= py && ty < py)) {
// 线段上与射线 Y 坐标相同的点的 X 坐标
var x = sx + (py - sy) * (tx - sx) / (ty - sy) // 点在多边形的边上
if (x === px) {
return Flag.on;
} // 射线穿过多边形的边界
if (x > px) {
flag = !flag
}
}
} // 射线穿过多边形边界的次数为奇数时点在多边形内
return flag ? Flag.in : Flag.out;
} }
class diamonds { private width: number = 180;
private height: number = 180;
id: string = "p" + new Date().getTime();;
node: JQuery<HTMLElement>;
left: number = 0;
top: number = 0;
constructor(isauto: boolean = true, isRe = true, left: number = 0, top: number = 0) {
this.left = left;
this.top = top;
if (isauto) { let dl = MathHelp.RandRange(200, 300);
let x = MathHelp.righttriangle(dl, 57);
let y = MathHelp.righttriangle(dl, 33);
let lastbox = diamondsList[diamondsList.length - 1];
if (isRe) {
if (direction == Direction.left) {
direction = Direction.right;
} else if (direction == Direction.right) {
direction = Direction.left;
}
}
if (direction == Direction.right) {
this.left = lastbox.left + x;
} else {
this.left = lastbox.left - x;
}
this.top = lastbox.top - y;
}
this.node = $(`<div id='${this.id}' class='gb' style="top:${this.top}px;left:${this.left}px">
<div class='box' style="background:url(img/c${MathHelp.RandRange(1, 4)}.png)"></div>
<div class='shadw'></div>
</div>`);
mask.append(this.node); }
GetPointList(): Pos[] {
var result = [{
x: this.left,
y: this.top + 57
}, {
x: this.left + (this.width / 2),
y: this.top + 4
}, {
x: this.left + this.width,
y: this.top + 57
}, {
x: this.left + (this.width / 2),
y: this.top + (57 * 2 - 4)
}];
return result;
}
move(p: Pos) {
this.node.css({
left: p.x + "px",
top: p.y + "px",
transition: "",
transform: ""
});
}
}
class Chess {
private width: number = 180;
private height: number = 182;
left: number = 49;
top: number = 531;
node: JQuery<HTMLElement>;
constructor() { this.node =$(`<div class="chess gb"></div>`);
mask.append(this.node);
}
jump(pt: Pos, call: Function) {
let numb = 0;
let t1 = setInterval(() => { if (numb == 0) {
this.node.animate({
left: pt.x + "px",
top: pt.y + "px"
}, 504); }
this.node.css({
"background-position": "-" + this.width * numb + "px" + " 0px"
});
numb++;
if (numb >= 11) {
window.clearInterval(t1);
call();
} }, 42) }
GetCenter(): Pos {
return {
x: this.left + this.width / 2,
y: this.top + this.height
}
}
move(p: Pos) {
this.node.css({
left: p.x + "px",
top: p.y + "px",
transition: "",
transform: ""
});
}
} class Game {
static distince = 0;
static time: number;
/**
* 初始化游戏场景
*/
static scence() {
let d1 = new diamonds(false, false, 50, 650);
diamondsList.push(d1);
let d = new diamonds(true, false);
diamondsList.push(d);
Game.loadlisten();
chess = new Chess();
$(".againBtn").on("click",()=>{
//重置
Game.GameRest(); });
}
/**
* 重置游戏
*/
static GameRest(){
$(".gameEnd").css({
"z-index":-1
});
diamondsList=[];
score=0;
$(".jfb").html(score.toString());
$(".gb").remove();
direction=Direction.right;
Game.scence(); }
static CreateSP() {
let d = new diamonds();
diamondsList.push(d);
Game.loadlisten();
}
private static loadlisten() {
document.addEventListener('touchstart', Game.touch, false);
document.addEventListener('touchmove', Game.touch, false);
document.addEventListener('touchend', Game.touch, false);
}
private static removelisten() {
document.removeEventListener('touchstart', Game.touch, false);
document.removeEventListener('touchmove', Game.touch, false);
document.removeEventListener('touchend', Game.touch, false);
}
private static touch(e: Event) {
e.preventDefault();
let currentDiamonds = diamondsList[diamondsList.length - 2];
if (e.type == "touchstart") {
//挤压形变动画
let scaley = 1;
let chessy = 0;
Game.distince = 0;
Game.time = setInterval(() => {
if (scaley > 0.7) {
scaley -= 0.01;
}
if (chessy < 30) {
chessy++;
chess.node.css({
"transform": " scaleX(" + (1 + chessy * 0.006) + ") scaleY(" + (1 - (chessy * 0.007)) + ")"
})
}
Game.distince++;
currentDiamonds.node.css({
"transform-origin": "bottom center",
"transform": "scaleY(" + scaley + ")"
}); }, 50); } else if (e.type == "touchend") {
//1.底座还原动画
//2.旗子动画轨迹
//3.落脚点判断
//4.场景平移,创建新底座,移除画外底座
currentDiamonds.node.css({
"transform": "scaleY(1)"
});
clearInterval(Game.time);
Game.removelisten();
Game.Jump(Game.distince); }
}
private static Jump(distince: number) {
let dl = distince * 17;
let x = MathHelp.righttriangle(dl, 57);
let y = MathHelp.righttriangle(dl, 33);
if (direction == Direction.left) {
x = -x;
}
chess.left = chess.left + x;
chess.top = chess.top - y;
chess.jump({ x: chess.left, y: chess.top }, () => {
let p = chess.GetCenter();
let last = diamondsList[diamondsList.length - 1];
let poly = last.GetPointList();
//判断是否跳在基座上
let result = MathHelp.rayCasting(p, poly);
if (result == Flag.in) {
direction = Math.random() > 0.5 ? 1 : 0;
Game.moveblock();
score++;
$(".jfb").html(score.toString());
} else {
//game over
$(".gameEnd").css({
"z-index":999
});
$(".score").html(score.toString());
console.log("game over!");
}
}) }
/**
* 移动场景
*/
private static moveblock() {
let last = diamondsList[diamondsList.length - 1];
let p1: Pos;
let x: number = 0;
let y: number = 0;
//以左右标准基座为左边平移
if (direction == Direction.left) {
p1 = { x: 50, y: 650 };
} else {
p1 = { x: 400, y: 650 };
}
x = p1.x - last.left;
y = p1.y - last.top; $(".gb").css({
"transform": "translate(" + x + "px," + y + "px)",
"transition": "transform 0.9s"
}); setTimeout(() => {
//更新class中left,top属性
$.each(diamondsList, (a, b) => {
b.left = b.left + x;
b.top = b.top + y;
b.move({ x: b.left, y: b.top });
});
chess.left = chess.left + x;
chess.top = chess.top + y;
chess.move({
x: chess.left,
y: chess.top
});
Game.Destroy();
//创建新底座
Game.CreateSP();
}, 1100)
}
//销毁画外的底座
private static Destroy(){
diamondsList.forEach((item,i,list)=>{ if(item.top>1008){
diamondsList.splice(i,1);
$("#"+item.id).remove();
}
})
}
}
Game.scence(); }

html:

 <!DOCTYPE html>
<html> <head>
<meta charset="utf-8" />
<title>Typescript跳一跳</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" />
<script src="http://lib.sinaapp.com/js/jquery/1.9.1/jquery-1.9.1.min.js"></script>
<link rel="stylesheet" type="text/css" href="css/ts.css" />
<script type="text/javascript">
var isios = false;
! function(userAgent) {
var screen_w = parseInt(window.screen.width),
scale = screen_w / 640;
if(/Android (\d+\.\d+)/.test(userAgent)) {
var version = parseFloat(RegExp.$1);
document.write(version > 2.3 ? '<meta name="viewport" content="width=640, initial-scale = ' + scale + ',user-scalable=1, minimum-scale = ' + scale + ', maximum-scale = ' + scale + ', target-densitydpi=device-dpi">' : '<meta name="viewport" content="width=640, target-densitydpi=device-dpi">');
} else {
isios = true;
document.write('<meta name="viewport" content="width=640, initial-scale = ' + scale + ' ,minimum-scale = ' + scale + ', maximum-scale = ' + scale + ', user-scalable=no, target-densitydpi=device-dpi">');
}
}(navigator.userAgent);
</script>
</head> <body> <!--游戏页面-->
<div class="game"> <div class="game-p">
<!--<div class="chess gb"></div>
<div id="one" class="gb">
<div class="box"></div>
<div class="shadw"></div>
</div>-->
</div>
<img class="logo" src="img/logo.png" />
<div class="jfb">0</div>
<div class="toolp">距离开启宝箱还有5步</div>
</div> <div class="gameEnd"> <div class="getScore"> <p class="score">10</p>
<button class="againBtn">再来一局</button> </div> </div> <script src="js/myjump.js" type="text/javascript" charset="utf-8"></script>
</body> </html>

css:

 html,
body {
margin:;
padding:;
height: 100%;
min-height: 1008px;
} .game {
height: 100%;
width: 100%;
position: relative;
left:;
top:;
} .logo {
position: absolute;
left: 30px;
top: 26px;
} .jfb {
position: absolute;
top: 30px;
right: 60px;
font-size: 100px;
font-weight:;
color: #4f4e3f;
text-align: center;
line-height: 100px;
} .toolp {
position: absolute;
bottom: 5%;
left: 30%;
width: 40%;
height: 50px;
border-radius: 50px;
color: #FFFFFF;
text-align: center;
font-size: 20px;
line-height: 50px;
background-color: #4a764e;
}
.game-p {
height: 100%;
width: 100%;
position: absolute;
left:;
top:;
background-color: #8aad8e;
}
.gb{
position: absolute;
left: 50px;
top: 650px; }
.box{
height: 180px;
width: 180px;
background-image:url(../img/c1.png);
background-size: 100% 100%;
z-index:;
position: absolute;
}
.shadw{
position: absolute;
left: 120px;
top:;
height: 133px;
width: 234px;
background-image: url(../img/s2.png);
background-size: 100% 100%;
opacity: 0.3;
transform: translateY(35px) translateX(-180px);
transform-origin: bottom center;
}
.chess{
width: 182px;
height: 227px;
background-image: url(../img/e3.png);
background-position:0 0;
position: absolute;
top: 531px;
left: 49px;
z-index:; }
.gameEnd{
position: absolute;
top:;
left:;
width: 100%;
height: 100%;
overflow: hidden;
background-color: rgba(0,0,0,.8);
z-index: -1;
}
.getScore{
width: 492px;
height: 760px;
background: url(../img/getScore.png) no-repeat;
background-size: 100% auto;
position: absolute;
top:;
right:;
left:;
bottom:;
margin: auto;
}
.score{
color: #dcc226;
font-size: 130px;
text-align: center;
margin-top: 120px;
font-weight:; }
.againBtn{
width: 309px;
height: 87px;
background: url(../img/bg.png) no-repeat;
background-size: 100% 100%;
font-size: 40px;
color: #dcc226;
text-align: center;
border: none;
font-weight:;
position: absolute;
left: 50%;
margin-left: -154.5px;
}

源码:留下邮箱,看到就发。

typescript 简版跳一跳的更多相关文章

  1. 用Kotlin破解Android版微信小游戏-跳一跳

    前言 微信又更新了,从更新日志上来看,似乎只是一次不痛不痒的小更新.不过,很快就有人发现,原来微信这次搞了个大动作——在小程序里加入了小游戏.今天也是朋友圈被刷爆的缘故. 看到网上 有人弄了一个破解版 ...

  2. 微信小程序跳一跳辅助程序(手动版)

    最近,微信官方推出了demo小程序游戏<跳一跳>,这个游戏操作简单,容易上手,却又不容易获得高分,受到很多人的喜爱(emm...这游戏有毒).自己也尝试了玩了几次,作为一个手残+脑残的资深 ...

  3. 微信跳一跳辅助Demo

    [原创] 前几天没事干看别人一直在玩微信上线的那一个跳一跳小游戏,玩着玩着老是掉下去,闲着没事呗 就想了想做一个辅助程序的呗.不过先做的手动版的.自动版的有点麻烦.就不发了.用的Java写的,也就一个 ...

  4. AI之微信跳一跳

    需要环境:1,Python3.6 2,android手机 3,ADB驱动,下载地址https://adb.clockworkmod.com/ 步骤: 配置Python3,ADB安装目录到环境变量pat ...

  5. 用Python代码实现微信跳一跳作弊器

    最近随着微信版本的更新,在进入界面有个跳一跳的小游戏,在网上看到技术篇教你用Python来玩微信跳一跳 ( 转载自 " 工科给事中的技术博客 " ) 本文旨在总结,技术全靠大神完成 ...

  6. java语言实现简单接口工具--粗简版

    2016注定是变化的一年,忙碌.网红.项目融资失败,现在有点时间整整帖子~~ 目标: 提高工作效率与质量,能支持平台全量接口回归测试与迭代测试也要满足单一接口联调测试. 使用人员: 测试,开发 工具包 ...

  7. python练习_购物车(简版)

    python练习_购物车(简版) 需求: 写一个python购物车可以输入用户初始化金额 可以打印商品,且用户输入编号,即可购买商品 购物时计算用户余额,是否可以购买物品 退出结算时打印购物小票 以下 ...

  8. 挑战App Store,微信通过“跳一跳”秀了一下“小程序”的肌肉

    2017年即将结束的时候,微信放了一个大招.随着最新的微信v6.6.1版本更新,基于小程序的"小游戏"板块正式上线.微信上首发的这款"小游戏"叫"跳一 ...

  9. .NET开发一个微信跳一跳辅助程序

    昨天微信更新了,出现了一个小游戏"跳一跳",玩了一下 赶紧还蛮有意思的 但纯粹是拼手感的,玩了好久,终于搞了个135分拿了个第一名,没想到过一会就被朋友刷下去了,最高的也就200来 ...

随机推荐

  1. Ubuntu 18.04添加新网卡

    在Ubuntu 18.04 LTS上配置IP地址的方法与旧方法有很大不同.与以前的版本不同,Ubuntu 18.04使用Netplan(一种新的命令行网络配置实用程序)来配置IP地址. 在这种新方法中 ...

  2. Eclipse中各种文件的注释与取消注释的快捷键

    Eclipse中各种文件的注释与取消注释的快捷键 Java文件: 注释和取消注释的快捷键都是:CTRL + / 或 Shift+Ctrl+C JS文件: 注释和取消注释的快捷键都是:CTRL + / ...

  3. vue过渡动画效果

    1 过渡基础 1.1 过渡的方式 Vue 在插入.更新或者移除 DOM 时,提供多种不同方式的应用过渡效果. 包括以下工具: 在 CSS 过渡和动画中自动应用 class 可以配合使用第三方 CSS ...

  4. react初学

    react和vue一样都是mvvm的这种开发模式. 下载js文件 引入HTML文件里 <!DOCTYPE html> <html> <head> <scrip ...

  5. Python 2.6.6升级到Python2.7.15

    最近在使用Python处理MySQL数据库相关问题时,需要用到Python2.7.5及以上版本,而centos6.5等版本操作系统默认自带的版本为2.6.6,因此需要对python进行升级. Pyth ...

  6. python字符串,数组操作

    今天倒是学到了很多知识,了解了python的基本数组,以及可变类型和不可变类型,还有元组,列表,字典等等的用法 然后作业如下 其中在做往list列表加东西时候遇到了小毛病,用户从控制台输入的是一个字符 ...

  7. Django的aggregate()和annotate()函数的区别

    aggregate() aggregate()为所有的QuerySet生成一个汇总值,相当于Count().返回结果类型为Dict. annotate() annotate()为每一个QuerySet ...

  8. Flask初见

    Flask是一个使用 Python 编写的轻量级 Web 应用框架.其 WSIG工具箱采用 Werkzeug ,模板引擎则使用 Jinja2 .Flask使用 BSD 授权. Flask也被称为 “m ...

  9. (数据科学学习手札13)K-medoids聚类算法原理简介&Python与R的实现

    前几篇我们较为详细地介绍了K-means聚类法的实现方法和具体实战,这种方法虽然快速高效,是大规模数据聚类分析中首选的方法,但是它也有一些短板,比如在数据集中有脏数据时,由于其对每一个类的准则函数为平 ...

  10. SAN---第二网的概念

    网络技术的优缺点:优点:连接能力,超强路由,管理能力,远距离缺点:低速以及高负载,强烈的软件需求,错误检测能力 SAN:storage area network(存储区域网络)--是一种基于光网的特殊 ...