diff --git a/teams/GoToTheDoor/BaseObjects.mbt b/teams/GoToTheDoor/BaseObjects.mbt new file mode 100644 index 0000000..0b14de4 --- /dev/null +++ b/teams/GoToTheDoor/BaseObjects.mbt @@ -0,0 +1,23 @@ +// 简单的类型定义 + +//坐标类 +struct Point { + mut x:Double + mut y:Double +} + +//速度类 +struct Velocity { + vx:Double + mut vy:Double +} + +//大小 +struct Size { + width:Double + height:Double +} + + + + diff --git a/teams/GoToTheDoor/LICENSE.txt b/teams/GoToTheDoor/LICENSE.txt new file mode 100644 index 0000000..f00c5e5 --- /dev/null +++ b/teams/GoToTheDoor/LICENSE.txt @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [Moonbug] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/teams/GoToTheDoor/README.md b/teams/GoToTheDoor/README.md index 3a25177..c671d82 100644 --- a/teams/GoToTheDoor/README.md +++ b/teams/GoToTheDoor/README.md @@ -8,6 +8,9 @@ Go to the door 是一款跑酷冒险类游戏,在充满邪念与恶意的地 包含多个陷阱关卡,每个关卡都有独特的挑战和谜题。 包含一个彩蛋关卡,你找到了吗? +# Moonbit版本 +moon 0.1.20241028 (2c58176 2024-10-28) + ## 制作者 xuancai-xiu diff --git a/teams/GoToTheDoor/map.mbt b/teams/GoToTheDoor/map.mbt new file mode 100644 index 0000000..38496c6 --- /dev/null +++ b/teams/GoToTheDoor/map.mbt @@ -0,0 +1,510 @@ +//关卡地图存储 +struct Map{ + // wall存储 + wall_list:Array[Wall] + // Object存储 + obj_list:Array[Object] + // 重力加速度 + g:Double + // 是否通关 + mut is_pass:Bool + // 记录时间 + mut time:Int + // 关卡号 + level_num:Int + // 是否反向 + inverse:Bool +} + + +// 关卡map的运行函数,在updtate里运行这个函数 +pub fn run(self:Map, player:Player) -> Unit { + // 物体的运行 + for i = 0; i < self.obj_list.length(); i = i + 1 { + self.obj_list[i].object_react(self, player) + } + // 刚体的运行 + for i = 0; i Map { + let mut map:Map = { + obj_list:[], + wall_list:[], + g:0.08, + is_pass:false, + time:0, + level_num:level, + inverse:false, + } + + // 每个关卡的初始化 + if (level == 0) { + let map0:Map = { + obj_list:[], + wall_list:[], + g:0.08, + is_pass:false, + time:0, + level_num:1, + inverse:false, + } + //地板一号的初始化 + let wall1:Wall = { + p:{x:0, y:140}, + size:{width:80, height:20}, + attributes:[1, 2, 3, 4] + } + //地板二号的初始化 + let wall2:Wall = { + p:{x:80, y:140}, + size:{width:80, height:20}, + attributes:[1] + } + let wall3:Wall = { + p:{x:80, y:80}, + size:{width:80, height:20}, + attributes:[1] + } + + let door:Object = { + p:{x:130, y:66}, + size:{width:10, height:20}, + v:{vx:0, vy:0}, + attributes:[2, 3], + } + //将初始化的wall,object加入map1,才能运行 + map0.wall_list.push(wall1) + map0.wall_list.push(wall2) + map0.wall_list.push(wall3) + map0.obj_list.push(door) + map = map0 + } else if (level == 1) { + let map1:Map = { + obj_list:[], + wall_list:[], + g:0.08, + is_pass:false, + time:0, + level_num:2, + inverse:false, + } + let wall1 = { + p:{x:0, y:140}, + size:{width:80, height:20}, + attributes:[1, 2, 3, 4, 14] + } + let wall2 = { + p:{x:80, y:140}, + size:{width:30, height:20}, + attributes:[1] + } + let wall3 = { + p:{x:110, y:140}, + size:{width:40, height:20}, + attributes:[1, 13] + } + let door = { + p:{x:135, y:126}, + size:{width:10, height:20}, + v:{vx:0, vy:0}, + attributes:[2, 3], + } + map1.wall_list.push(wall1) + map1.wall_list.push(wall2) + map1.wall_list.push(wall3) + map1.obj_list.push(door) + map = map1 + } else if (level == 2) { + let map2:Map = { + obj_list:[], + wall_list:[], + g:0.08, + is_pass:false, + time:0, + level_num:3, + inverse:false, + } + let wall1:Wall = { + p:{x:0, y:120}, + size:{width:30, height:40}, + attributes:[1] + } + let wall2:Wall = { + p:{x:45, y:120}, + size:{width:30, height:40}, + attributes:[1,10] + } + let wall3:Wall = { + p:{x:90, y:120}, + size:{width:30, height:40}, + attributes:[1,11] + } + let wall4:Wall = { + p:{x:120, y:60}, + size:{width:40, height:100}, + attributes:[1,12] + } + let wall5:Wall = { + p:{x:45, y:120}, + size:{width:10, height:20}, + attributes:[1,9] + } + let door:Object = { + p:{x:140, y:46}, + size:{width:10, height:20}, + v:{vx:0, vy:0}, + attributes:[2, 3], + } + map2.wall_list.push(wall1) + map2.wall_list.push(wall2) + map2.wall_list.push(wall3) + map2.wall_list.push(wall4) + map2.wall_list.push(wall5) + map2.obj_list.push(door) + map = map2 + } else if (level == 3) { + let map3:Map = { + obj_list:[], + wall_list:[], + g:0.08, + is_pass:false, + time:0, + level_num:4, + inverse:false, + } + let leftPlatform1:Wall = { + p:{x:0, y:80}, + size:{width:10, height:10}, + attributes:[1] + } + let rightPlatform1:Wall = { + p:{x:150, y:80}, + size:{width:30, height:10}, + attributes:[1] + } + let platform1:Wall = { + p:{x:20, y:120}, + size:{width:20, height:10}, + attributes:[1, 15] + } + let platform2:Wall = { + p:{x:50, y:60}, + size:{width:50, height:10}, + attributes:[1, 16] + } + let platform3:Wall = { + p:{x:110, y:120}, + size:{width:30, height:10}, + attributes:[1, 17] + } + let door:Object = { + p:{x:150, y:66}, + size:{width:10, height:20}, + v:{vx:0, vy:0}, + attributes:[2, 3], + } + let easterEgg:Object = { + p:{x:50, y:140}, + size:{width:40, height:20}, + v:{vx:0, vy:0}, + attributes:[1, 7, 8] + } + map3.wall_list.push(leftPlatform1) + map3.wall_list.push(rightPlatform1) + map3.wall_list.push(platform1) + map3.wall_list.push(platform2) + map3.wall_list.push(platform3) + map3.obj_list.push(door) + map3.obj_list.push(easterEgg) + map = map3 + } else if (level == 4) { + let map4:Map = { + obj_list:[], + wall_list:[], + g:0.08, + is_pass:false, + time:0, + level_num:5, + inverse:false, + } + let wall1:Wall = { + p:{x:0, y:60}, + size:{width:20, height:100}, + attributes:[1] + } + let wall2:Wall = { + p:{x:36, y:60}, + size:{width:10, height:6}, + attributes:[1,5] + } + let wall3:Wall = { + p:{x:62, y:60}, + size:{width:10, height:6}, + attributes:[1,6] + } + let wall4:Wall = { + p:{x:88, y:60}, + size:{width:10, height:6}, + attributes:[1] + } + let wall5:Wall = { + p:{x:114, y:60}, + size:{width:10, height:6}, + attributes:[1,8] + } + let wall6:Wall = { + p:{x:140, y:120}, + size:{width:20, height:100}, + attributes:[1] + } + let wall7:Wall = { + p:{x:88, y:120}, + size:{width:10, height:6}, + attributes:[1,7] + } + let door:Object = { + p:{x:150, y:106}, + size:{width:10, height:20}, + v:{vx:0, vy:0}, + attributes:[2, 3], + } + // 同理 + map4.wall_list.push(wall1) + map4.wall_list.push(wall2) + map4.wall_list.push(wall3) + map4.wall_list.push(wall4) + map4.wall_list.push(wall5) + map4.wall_list.push(wall6) + map4.wall_list.push(wall7) + map4.obj_list.push(door) + map = map4 + } else if (level == 5) { + let map5:Map = { + obj_list:[], + wall_list:[], + g:0.08, + is_pass:false, + time:0, + level_num:6, + inverse:true, + } + // let ceiling: Wall = { + // p:{x:0, y:0}, + // size:{width:160, height:2}, + // attributes:[1] + // } + let floor: Wall = { + p:{x:0, y:140}, + size:{width:160, height:20}, + attributes:[1] + } + let wall_left:Wall = { + p:{x:0, y: 0}, + size:{width:1, height:160}, + attributes:[1] + } + let wall_right:Wall = { + p:{x:160, y: 0}, + size:{width:1, height:160}, + attributes:[1] + } + let door:Object = { + p:{x:140, y:126}, + size:{width:10, height:20}, + v:{vx:0, vy:0}, + attributes:[2, 3], + } + let spike1:Object = { + p:{x:50, y:139}, + size:{width:4, height:3}, + v:{vx:0, vy:0}, + attributes:[4,5] + } + let spike2:Object = { + p:{x:110, y:139}, + size:{width:4, height:3}, + v:{vx:5, vy:0}, + attributes:[4,5,6] + } + let spike3:Object = { + p:{x:10, y:139}, + size:{width:4, height:3}, + v:{vx:5, vy:0}, + attributes:[4,5] + } + // map4.wall_list.push(ceiling) + map5.wall_list.push(floor) + map5.wall_list.push(wall_left) + map5.wall_list.push(wall_right) + map5.obj_list.push(door) + map5.obj_list.push(spike1) + map5.obj_list.push(spike2) + map5.obj_list.push(spike3) + map = map5 + } else if (level == 6) { + let map7:Map = { + obj_list:[], + wall_list:[], + g:0.07, + is_pass:false, + time:0, + level_num:8, + inverse:false, + } + let wall1:Wall = { + p:{x:0, y:120}, + size:{width:20, height:40}, + attributes:[1] + } + let wall2:Wall = { + p:{x:60, y:60}, + size:{width:40, height:120}, + attributes:[1] + } + let wall3:Wall = { + p:{x:100, y:120}, + size:{width:60, height:40}, + attributes:[1,18] + } + let spring1:Object = { + p:{x:25, y:140}, + size:{width:4, height:4}, + v:{vx:0, vy:0}, + attributes:[11,12] + } + let spring2:Object = { + p:{x:100, y:117}, + size:{width:4, height:4}, + v:{vx:0, vy:0}, + attributes:[11,12] + } + let portals1:Object = { + p:{x:55, y:100}, + size:{width:6, height:8}, + v:{vx:0, vy:0}, + attributes:[13,14,17] + } + let portals2:Object = { + p:{x:100, y:60}, + size:{width:6, height:8}, + v:{vx:0, vy:0}, + attributes:[13,15] + } + let portals3:Object = { + p:{x:135, y:10}, + size:{width:6, height:8}, + v:{vx:0, vy:0.8}, + attributes:[13,16,18] + } + let door:Object = { + p:{x:70, y:46}, + size:{width:10, height:20}, + v:{vx:0, vy:0}, + attributes:[2, 3, 9], + } + map7.wall_list.push(wall1) + map7.wall_list.push(wall2) + map7.wall_list.push(wall3) + map7.obj_list.push(spring1) + map7.obj_list.push(spring2) + map7.obj_list.push(portals1) + map7.obj_list.push(portals2) + map7.obj_list.push(portals3) + map7.obj_list.push(door) + map = map7 + }else if (level == 7) { + let map6:Map = { + obj_list:[], + wall_list:[], + g:0.08, + is_pass:false, + time:0, + level_num:7, + inverse:false, + } + + // 地板一号的初始化 + let wall1:Wall = { + p:{x:0, y:140}, + size:{width:140, height:20}, + attributes:[1] + } + let wall2:Wall = { + p:{x:100, y:120}, + size:{width:40, height:20}, + attributes:[1] + } + let spring1:Object = { + p:{x:70, y:134}, + size:{width:6, height:6}, + v:{vx:0, vy:0}, + attributes:[11,12] + } + let spring2:Object = { + p:{x:40, y:134}, + size:{width:6, height:6}, + v:{vx:0, vy:0}, + attributes:[11,12] + } + let trophy:Object = { + p:{x:120, y:100}, + size:{width:0, height:0}, + v:{vx:0, vy:0}, + attributes:[19] + } + let thank_word:Object = { + p:{x:0, y:40}, + size:{width:0, height:0}, + v:{vx:0, vy:0}, + attributes:[1] + } + // 同理 + map6.wall_list.push(wall1) + map6.wall_list.push(wall2) + map6.obj_list.push(spring1) + map6.obj_list.push(spring2) + map6.obj_list.push(trophy) + map6.obj_list.push(thank_word) + map = map6 + }else if (level == 8) { + // 彩蛋关卡 + let mapEag:Map = { + obj_list:[], + wall_list:[], + g:0.08, + is_pass:false, + time:0, + level_num:0, + inverse:false, + } + let wall1:Wall = { + p:{x:0, y:140}, + size:{width:160, height:20}, + attributes:[1,20] + } + let eggWord:Object = { + p:{x:5, y:15}, + size:{width:0, height:0}, + v:{vx:0, vy:0}, + attributes:[10,20] + } + let door:Object = { + p:{x:260, y:126}, + size:{width:10, height:20}, + v:{vx:0, vy:0}, + attributes:[2, 3, 9,20], + } + mapEag.wall_list.push(wall1) + mapEag.obj_list.push(eggWord) + mapEag.obj_list.push(door) + map = mapEag + } + return map +} \ No newline at end of file diff --git a/teams/GoToTheDoor/object.mbt b/teams/GoToTheDoor/object.mbt new file mode 100644 index 0000000..7a56f72 --- /dev/null +++ b/teams/GoToTheDoor/object.mbt @@ -0,0 +1,252 @@ +// 物体类 +struct Object{ + // 物体的左上角 + p:Point + // 物体的大小 + size:Size + // 物体速度 + v:Velocity + // attribute存储了object使用函数的索引 + attributes:Array[Int] +} + + +// 根据attribute的数值,选择object函数 +pub fn object_react(self:Object, map:Map, player:Player)->Unit{ + for i=0;ishowThankWord(self) + 2=>showOval(self) + 3=>getDoor(self, map, player) + 4=>showSpike(self) + 5=>getSpike(self, map, player) + 6=>moveSpike(self, player) + 7=>showEasterEgg(self) + 8=>getInEasterEggLevel(self, map, player) + 9=>getOutEasterEggLevel(self, player) + 10=>showEag(self) + 11=>showSpring(self) + 12=>getSpring(self,player) + 13=>showPortals(self) + 14=>getPortals(self,player,140,110) + 15=>getPortals(self,player,50,140) + 16=>getPortals(self,player,70,40) + 17=>portalsTeleportation(self,player) + 18=>portalsMovedown(self,player) + 19=>drawTrophy(self) + 20=>map_move(self,player) + _=>continue + } + } +} + +pub fn getInEasterEggLevel(self:Object, map:Map, player:Player) -> Unit { + if player.obj.p.x >= self.p.x && player.obj.p.y >= self.p.y && player.obj.p.y + player.obj.size.height <= self.p.y + self.size.height { + map.is_pass = true + hasEasterEgg.value = true + } +} + +pub fn getOutEasterEggLevel(self:Object, player:Player) -> Unit { + if player.obj.p.x >= self.p.x && player.obj.p.y >= self.p.y && player.obj.p.y + player.obj.size.height <= self.p.y + self.size.height { + hasEasterEgg.value = false + } +} + +pub fn showEasterEgg(self:Object) -> Unit { + let x:Int=self.p.x.to_int() + let y:Int=self.p.y.to_int() + @wasm4.set_draw_colors(index = 1, 4) + @wasm4.oval(x, y, self.size.width.to_int(), self.size.height.to_int()) +} +pub fn getDoor(self:Object, map:Map, player:Player) -> Unit { + if player.obj.p.x >= self.p.x && player.obj.p.y >= self.p.y && player.obj.p.y + player.obj.size.height <= self.p.y + self.size.height { + map.is_pass = true + } +} + +pub fn showThankWord(self:Object) -> Unit { + let x:Int=self.p.x.to_int() + let y:Int=self.p.y.to_int() + @wasm4.text("Congratulations!!! \nYou've passed all \n Thanks for playing!", x, y) +} + +pub fn showEag(self:Object) -> Unit { + let x:Int=self.p.x.to_int() + let y:Int=self.p.y.to_int() + @wasm4.text("Contributors:", x, y) + @wasm4.text("xuancai-xiu", x, y+15) + @wasm4.text("artist123487654", x, y+30) + @wasm4.text("nagisa", x, y+45) + @wasm4.text("SKw6668888", x, y+60) + @wasm4.text("K-ON!", x+55, y+77) + @wasm4.text("More inform...", x+130, y) + @wasm4.text("Bilibili videw: ", x+130, y+15) + @wasm4.text("GoToTheDoor实况", x+130, y+30) + @wasm4.text("CSDN article: ", x+130, y+45) + @wasm4.text("......", x+130, y+60) + + // 设置箭头颜色,选择红色和黑色 + @wasm4.set_draw_colors(index=1, 3); // 颜色:红色和黑色 + + let x: Int = self.p.x.to_int()+100; + let y: Int = self.p.y.to_int()+80; + + // 画箭头的箭身(长条矩形) + @wasm4.rect(x, y, 20, 2); // 箭身:宽20,高4 + + // 画箭头的箭头部分(使用两条线段来模拟三角形) + @wasm4.line(x + 20, y - 6, x + 30, y); // 第一条线:箭头的上半部分 + @wasm4.line(x + 20, y + 6, x + 30, y); // 第二条线:箭头的下半部分 + @wasm4.line(x + 19, y - 6, x + 29, y); // 第一条线:箭头的上半部分 + @wasm4.line(x + 19, y + 6, x + 29, y); // 第二条线:箭头的下半部分 +} + +pub fn showOval(self:Object) -> Unit { + let x:Int=self.p.x.to_int() + let y:Int=self.p.y.to_int() + @wasm4.set_draw_colors(index = 1, 1) + @wasm4.oval(x, y, self.size.width.to_int(), self.size.height.to_int()) +} + +pub fn showSpike(self:Object) -> Unit { + let x:Int=self.p.x.to_int() + let y:Int=self.p.y.to_int() + let width:Int=self.size.width.to_int() + let height:Int=self.size.height.to_int() + @wasm4.set_draw_colors(index = 1, 2) + for i=0;i Unit { + let x:Int=self.p.x.to_int() + let y:Int=self.p.y.to_int() + let xx:Int=player.obj.p.x.to_int() + let yy:Int=player.obj.p.y.to_int() + let w:Int=player.obj.size.width.to_int() + let h:Int=player.obj.size.height.to_int() + let width:Int=self.size.width.to_int() + if yy+h+xx+w-x-y>=0 && yy+h-xx+x+width-1-y>=0{ + map.is_pass = false + player.is_dead = true + } +} + +pub fn moveSpike(self:Object, player:Player) -> Unit { + if player.obj.p.x >= self.p.x - 7 && self.p.x < 130{ + self.p.x += self.v.vx + } +} + +//弹簧的渲染函数 +pub fn showSpring(self:Object)->Unit{ + let x:Int=self.p.x.to_int() + let y:Int=self.p.y.to_int() + let width:Int=self.size.width.to_int() + let height:Int=self.size.height.to_int() + @wasm4.set_draw_colors(index = 1, 2) + @wasm4.line(x,y,x+width,y) + @wasm4.line(x+width/2,y,x+width/2,y+height) +} + +//检测是否碰到弹簧,弹簧碰到就起飞 +pub fn getSpring(self:Object,player:Player)->Unit{ + let x:Int=self.p.x.to_int() + let y:Int=self.p.y.to_int() + let xx:Int=player.obj.p.x.to_int() + let yy:Int=player.obj.p.y.to_int() + let w:Int=player.obj.size.width.to_int() + let h:Int=player.obj.size.height.to_int() + let width:Int=self.size.width.to_int() + let height:Int=self.size.height.to_int() + if xx+w-x>=0 && xx-x-width<=0 && yy+h-y>=0 && yy-y-height <=0 { + player.obj.v.vy=-player.jump_v*2 + playJumpSound() + } +} + +//传送门显示 +pub fn showPortals(self:Object) -> Unit { + let x:Int=self.p.x.to_int() + let y:Int=self.p.y.to_int() + @wasm4.set_draw_colors(index = 1, 4) + @wasm4.oval(x, y, self.size.width.to_int(), self.size.height.to_int()) +} + +pub fn getPortals(self:Object,player:Player,to_x:Int,to_y:Int)->Unit{ + let x:Int=self.p.x.to_int() + let y:Int=self.p.y.to_int() + let xx:Int=player.obj.p.x.to_int() + let yy:Int=player.obj.p.y.to_int() + let w:Int=player.obj.size.width.to_int() + let h:Int=player.obj.size.height.to_int() + let width:Int=self.size.width.to_int() + let height:Int=self.size.height.to_int() + if xx+w-x>=0 && xx-x-width<=0 && yy+h-y>=0 &&yy-y-height <=0 { + player.obj.p.x=to_x.to_double() + player.obj.p.y=to_y.to_double() //传送 + } +} + +pub fn portalsTeleportation(self:Object,player:Player)->Unit { + if player.obj.p.x > 45 && player.obj.p.x <50 { + self.p.x=35 + self.p.y=140 + } +} + +pub fn portalsMovedown(self:Object,player:Player)->Unit { + if player.obj.p.x < 105 && player.obj.p.x >95 && self.p.y<=85 { + self.p.y += self.v.vy + } +} + +pub fn drawTrophy(self:Object) -> Unit { + @wasm4.set_draw_colors(index=1, 3); + let x: Int = self.p.x.to_int(); + let y: Int = self.p.y.to_int(); + + // 奖杯底座(加厚底座) + @wasm4.rect(x - 6, y + 18, 12, 4); // 底座宽12,高4 + + // 奖杯支架(装饰支架) + @wasm4.rect(x - 3, y + 14, 6, 4); // 支架宽6,高4 + + // 奖杯杯身(加厚设计) + @wasm4.rect(x - 4, y + 4, 8, 10); // 杯身宽8,高10 + + // 奖杯杯口(加装饰的杯口) + @wasm4.rect(x - 5, y + 2, 10, 3); // 杯口宽10,高3 + + // 奖杯把手左侧(更具装饰性) + @wasm4.rect(x - 8, y + 6, 3, 6); // 左把手宽3,高6 + @wasm4.rect(x - 9, y + 7, 5, 2); // 左把手连接部分 + + // 奖杯把手右侧(与左把手对称) + @wasm4.rect(x + 5, y + 6, 3, 6); // 右把手宽3,高6 + @wasm4.rect(x + 4, y + 7, 5, 2); // 右把手连接部分 + + // 奖杯杯身装饰线条(增加层次感) + @wasm4.rect(x - 3, y + 6, 6, 2); // 杯身装饰线,宽6,高2 + @wasm4.rect(x - 3, y + 12, 6, 2); // 中部装饰线,宽6,高2 + + // 奖杯顶部的装饰细节(做一些细小的点缀) + @wasm4.rect(x - 1, y + 1, 1, 1); // 顶部装饰点 + @wasm4.rect(x + 3, y + 1, 1, 1); // 顶部装饰点 +} + +pub fn map_move(self:Object,player:Player)->Unit { + if @wasm4.get_gamepad(index=1).button_left { + if player.obj.p.x >=0 { + self.p.x+=player.obj.v.vx*1.2 + } + } + if @wasm4.get_gamepad(index=1).button_right { + if player.obj.p.x <= 154 { + self.p.x-=player.obj.v.vx*1.2 + } + } +} \ No newline at end of file diff --git a/teams/GoToTheDoor/player.mbt b/teams/GoToTheDoor/player.mbt new file mode 100644 index 0000000..92cc37e --- /dev/null +++ b/teams/GoToTheDoor/player.mbt @@ -0,0 +1,306 @@ +// 玩家类 +struct Player { + obj:Object + // 跳跃大小 + jump_v:Double + // 是否死亡 + mut is_dead:Bool + // 玩家状态 + mut state:Int + // 跳跃冷却 + mut jumpTimer:Int +} + + +//玩家运行函数,玩家控制,渲染都集中在这里 +pub fn player_init(level:Int) -> Player { + let mut xx = 0.0 + let mut yy = 0.0 + if level == 0 { + xx = 145 + yy = 110 + } else if level == 1 { + xx = 100 + yy = 100 + } else if level == 3 { + xx = 0 + yy = 60 + } else if level == 2 || level == 6 || level == 7 || level == 9 { + xx = 10 + yy = 100 + } else if level == 4 { + xx = 10 + yy = 45 + } else if level == 5 { + xx = 25 + yy = 100 + } else if level == 8 { + xx = 10 + yy = 100 + } + + let player:Player = { + obj:{ + p:{x:xx, y:yy}, + size:{width:6, height:12}, + v:{vx:0.5, vy:0}, + attributes:[] + }, + jump_v:1.35, + is_dead:false, + state:-1, + jumpTimer:0, + } + return player +} +pub fn player_react(self:Player, map:Map) -> Unit { + let time = map.time + // 检测按键输入控制玩家 + self.control(map) + // 跳跃冷却,不能跳跃完立马跳跃 + if self.jumpTimer > 0 { + self.jumpTimer -= 1 + } + // 玩家状态机,每个状态代表玩家的某个动作状态,用以确定渲染小人画面 + if self.state == -1 { + self.show1(map) + } else if self.state == 0 { + self.show3(map) + } else if self.state == 1 { + self.show2(map) + } else if self.state == 2 && time < 5 { + self.show1(map) + } else if self.state == 2 && time < 10 { + self.show31(map) + } else if self.state == 2 && time < 15 { + self.show3(map) + } else if self.state == 2 { + self.show31(map) + } else if self.state == 3 && time < 5 { + self.show1(map) + } else if self.state == 3 && time < 10 { + self.show21(map) + } else if self.state == 3 && time < 15 { + self.show2(map) + } else if self.state == 3 { + self.show21(map) + } +} + + +// 碰撞检测,返回Bool供control函数控制移动 + +pub fn groundDetect(self:Player,map:Map)->Bool { + // 地面检测 + for ground in map.wall_list { + if self.obj.p.y + self.obj.size.height + 0.05 >= ground.p.y && self.obj.p.x + self.obj.size.width - 0.05 >= ground.p.x && self.obj.p.x + 0.05 <= ground.p.x + ground.size.width && self.obj.p.y < ground.p.y { + // 调整玩家位置到地面上方 (不会陷入地面) + self.obj.p.y = ground.p.y - self.obj.size.height; + return true + } + } + return false +} + +pub fn wallDetect(self:Player,map:Map, facingdir:Int)->Bool { + // 墙检测 + for wall in map.wall_list { + if facingdir == 0 { + if self.obj.p.x <= wall.p.x + wall.size.width && self.obj.p.x >= wall.p.x && (wall.p.y <= self.obj.p.y && wall.p.y + wall.size.height >= self.obj.p.y || wall.p.y >= self.obj.p.y && wall.p.y + 1 < self.obj.p.y + self.obj.size.height) { + return true + } + } else if facingdir == 1 { + if self.obj.p.x + self.obj.size.width >= wall.p.x && self.obj.p.x <= wall.p.x && (wall.p.y <= self.obj.p.y && wall.p.y + wall.size.height >= self.obj.p.y || wall.p.y >= self.obj.p.y && wall.p.y + 1 < self.obj.p.y + self.obj.size.height) { + return true + } + } + } + return false +} + +// 玩家控制函数 +pub fn control(self:Player, map:Map)->Unit { + // 下降到一定界限,玩家死亡 + if self.obj.p.y >= 148 { + self.is_dead = true + } + // 静止站立状态 + if self.obj.v.vy == 0 { + self.state = -1 + } + + // x右移?(左) + if @wasm4.get_gamepad(index=1).button_right && self.obj.p.x + self.obj.size.width <= 160 && not(wallDetect(self, map, 0)) && map.inverse == true { + self.obj.p.x -= self.obj.v.vx + if self.obj.v.vy == 0 { + self.state = 2 + } else { + self.state = 0 + } + } + + // x左移?(右) + else if @wasm4.get_gamepad(index=1).button_left && self.obj.p.x >= 0 && not(wallDetect(self, map, 1)) && map.inverse == true { + self.obj.p.x += self.obj.v.vx + if self.obj.v.vy == 0 { + self.state = 3 + } else { + self.state = 1 + } + } + + // x右移 + else if @wasm4.get_gamepad(index=1).button_right && self.obj.p.x + self.obj.size.width <= 160 && not(wallDetect(self, map, 1)) { + self.obj.p.x += self.obj.v.vx + if self.obj.v.vy == 0 { + self.state = 3 + } else { + self.state = 1 + } + } + + // x左移 + else if @wasm4.get_gamepad(index=1).button_left && self.obj.p.x >= 0 && not(wallDetect(self, map, 0)) { + self.obj.p.x -= self.obj.v.vx + if self.obj.v.vy == 0 { + self.state = 2 + } else { + self.state = 0 + } + } + + // y轴跳跃(有加速度) + + // 有地板才能跳跃 + if @wasm4.get_gamepad(index=1).button_up && groundDetect(self, map) && self.jumpTimer == 0 { + self.obj.v.vy = -self.jump_v + self.obj.p.y += self.obj.v.vy + playJumpSound() + self.jumpTimer = 40 + if self.state == 2 { + self.state = 0 + } else { + self.state = 1 + } + } + + if not(groundDetect(self, map)) { + self.obj.v.vy += map.g + } else { + self.obj.v.vy = 0 + } + + self.obj.p.y += self.obj.v.vy +} + +//死亡函数 +pub fn die(self:Player)->Unit{ + self.is_dead = true +} +// player渲染函数 + +// 玩家显示形象 + +// 待机形象 +pub fn show1(self: Player, map: Map) -> Unit { + map.time+=0 + @wasm4.set_draw_colors(index=1, 3); + let x: Int = self.obj.p.x.to_int(); + let y: Int = self.obj.p.y.to_int(); + // 右脚部 + @wasm4.rect(x, y + 9, 2, 4); + // 左脚部 + @wasm4.rect(x + 4, y + 9, 2, 4); + // 身体 + @wasm4.rect(x, y + 3, 6, 6); + // 头部 + @wasm4.rect(x + 1, y, 4, 3); +} + +// 向右形象 +pub fn show2(self: Player, map: Map) -> Unit { + map.time+=0 + @wasm4.set_draw_colors(index=1, 3); + let x: Int = self.obj.p.x.to_int(); + let y: Int = self.obj.p.y.to_int(); + // 右脚部 + @wasm4.rect(x + 6, y + 7, 2, 4); + // 左脚部 + @wasm4.rect(x - 2, y + 9, 4, 2); + // 身体 + @wasm4.rect(x, y + 4, 6, 6); + // 手臂 + @wasm4.rect(x - 1, y + 4, 1, 4); + // 头部 + @wasm4.rect(x + 1, y + 1, 4, 4); +} + +pub fn show21(self: Player, map: Map) -> Unit { + map.time+=0 + @wasm4.set_draw_colors(index=1, 3); + let x: Int = self.obj.p.x.to_int(); + let y: Int = self.obj.p.y.to_int(); + // 右脚部 + @wasm4.rect(x + 5, y + 9, 2, 4); + // 左脚部 + @wasm4.rect(x - 1, y + 10, 3, 2); + // 身体 + @wasm4.rect(x, y + 4, 6, 6); + // 手臂 + @wasm4.rect(x -1, y + 4, 1, 4); + // 头部 + @wasm4.rect(x + 1, y + 1, 4, 4); +} + +// 向左形象 +pub fn show3(self: Player, map: Map) -> Unit { + map.time+=0 + @wasm4.set_draw_colors(index=1, 3); + let x: Int = self.obj.p.x.to_int(); + let y: Int = self.obj.p.y.to_int(); + // 右脚部 + @wasm4.rect(x + 4, y + 9, 4, 2); + // 左脚部 + @wasm4.rect(x - 2, y + 7, 2, 4); + // 身体 + @wasm4.rect(x, y + 4, 6, 6); + // 手臂 + @wasm4.rect(x + 6, y + 4, 1, 4); + // 头部 + @wasm4.rect(x + 1, y + 1, 4, 4); +} + +pub fn show31(self: Player, map: Map) -> Unit { + map.time += 0 + @wasm4.set_draw_colors(index=1, 3); + let x: Int = self.obj.p.x.to_int(); + let y: Int = self.obj.p.y.to_int(); + // 右脚部 + @wasm4.rect(x + 3, y + 10, 3, 2); + // 左脚部 + @wasm4.rect(x - 1, y + 9, 2, 4); + // 身体 + @wasm4.rect(x, y + 4, 6, 6); + // 手臂 + @wasm4.rect(x + 6, y + 4, 1, 4); + // 头部 + @wasm4.rect(x + 1, y + 1, 4, 4); +} + +// 死亡形象 +pub fn show4(self: Player, map: Map) -> Unit { + map.time+=0 + @wasm4.set_draw_colors(index=1, 3); + let x: Int = self.obj.p.x.to_int(); + let y: Int = self.obj.p.y.to_int(); + // 右脚部 + @wasm4.rect(x, y + 9, 2, 4); + // 左脚部 + @wasm4.rect(x + 4, y + 9, 2, 4); + // 身体 + @wasm4.rect(x + 2, y + 4, 2, 7); + // 手臂 + @wasm4.rect(x - 1, y + 4, 8, 2); + // 头部 + @wasm4.rect(x + 1, y + 2, 4, 4); +} diff --git a/teams/GoToTheDoor/sound.mbt b/teams/GoToTheDoor/sound.mbt new file mode 100644 index 0000000..cd0e112 --- /dev/null +++ b/teams/GoToTheDoor/sound.mbt @@ -0,0 +1,33 @@ +// 音效 + +// 跳跃音效 +pub fn playJumpSound() -> Unit { + @wasm4.tone( + (400, 500), + @wasm4.ADSR::new(5), + @wasm4.ADSRVolume::new(100), + @wasm4.ToneFlag::new(), + ) +} + +// 通关音效 +pub fn passSound() -> Unit { + @wasm4.tone( + (500, 500), + @wasm4.ADSR::new(30), + @wasm4.ADSRVolume::new(100), + @wasm4.ToneFlag::new(), + ) +} + +// 死亡音效 +pub fn deathSound() -> Unit { + @wasm4.tone( + (430, 90), + @wasm4.ADSR::new(45), + @wasm4.ADSRVolume::new(100), + @wasm4.ToneFlag::new(), + ) +} + + diff --git a/teams/GoToTheDoor/top.mbt b/teams/GoToTheDoor/top.mbt new file mode 100644 index 0000000..f648918 --- /dev/null +++ b/teams/GoToTheDoor/top.mbt @@ -0,0 +1,106 @@ +//创建一个可变类型,表示关卡索引 +let map:Ref[Map] = {value:map_init(0)} //初始化第一关 +let maptop:Ref[Int] = {value:0} + +//最大关卡数-1 +let max_top:Int = 8 + +//玩家初始化 +let player:Ref[Player] = {value:player_init(0)} + +let showDeathTimer:Ref[Int] = {value:0} + +let temp:Ref[Int] = {value:0} + +let deathCount:Ref[Int] = {value:0} + +let hasEasterEgg:Ref[Bool] = {value:false} + +pub fn start() -> Unit { +} + +pub fn update() -> Unit { + if player.value.is_dead == false{ + if (map.value.level_num != 7) { + @wasm4.text("Level \{map.value.level_num}", 54, 0) //打印关卡 + } + player.value.player_react(map.value) + map.value.run(player.value) + } else { + //玩家死亡逻辑 // 大家可以写鼓励或者嘲讽的话 + if (deathCount.value == 0) { + @wasm4.text("You failed!", 40, 20) + @wasm4.text("fail \{deathCount.value + 1} times", 34, 36) + @wasm4.text("Rise, warrior!", 34, 52) + @wasm4.text("Your determination", 10, 68) + @wasm4.text("will lead you", 34, 84) + @wasm4.text("to victory", 38, 100) + } else if (deathCount.value == 1) { + @wasm4.text("You failed!", 40, 20) + @wasm4.text("fail \{deathCount.value + 1} times", 34, 36) + @wasm4.text("Don't give up!", 30, 52) + @wasm4.text("Every failure brings", 0, 68) + @wasm4.text("you", 60, 84) + @wasm4.text("closer to success", 12, 100) + } else if (deathCount.value == 2) { + @wasm4.text("You failed!", 40, 20) + @wasm4.text("fail \{deathCount.value + 1} times", 34, 36) + @wasm4.text("Every attempt", 32, 52) + @wasm4.text("is a step forward", 14, 68) + @wasm4.text("Keep going!", 40, 84) + } else if (deathCount.value == 3) { + @wasm4.text("You failed!", 40, 20) + @wasm4.text("fail \{deathCount.value + 1} times", 34, 36) + @wasm4.text("You're stronger", 20, 52) + @wasm4.text("than", 58, 68) + @wasm4.text("this obstacle", 32, 84) + @wasm4.text("Keep fighting!", 28, 100) + } else { + @wasm4.text("You failed!", 40, 20) + @wasm4.text("fail \{deathCount.value + 1} times", 34, 36) + @wasm4.text("What can I say?", 20, 72) + } + // 禁止玩家输入 + player.value.is_dead = true + // 播放死亡动画 + showDeathTimer.value += 1 + player.value.show4(map.value) + + // 播放死亡音效 + if (showDeathTimer.value == 1) { + deathSound() + } + if (showDeathTimer.value > 120) { + deathCount.value += 1 + map.value = map_init(maptop.value) + player.value = player_init(maptop.value) + showDeathTimer.value = 0 + } + } + + if map.value.is_pass == true { + deathCount.value = 0 + // 通关逻辑 + // 通关音效 + // 打印过关 + @wasm4.text("You passed!", 40, 20) + if (temp.value == 0) { + passSound() + } + temp.value += 1 + // 如果还有下一关,则下一关 + // 彩蛋关卡 + if hasEasterEgg.value == true { + map.value = map_init(8) + player.value = player_init(8) + temp.value = 0 + } else { + if maptop.value < max_top && temp.value > 45 { + maptop.value += 1 + map.value = map_init(maptop.value) + player.value = player_init(maptop.value) + temp.value = 0 + } + } + } +} diff --git a/teams/GoToTheDoor/utils.mbt b/teams/GoToTheDoor/utils.mbt new file mode 100644 index 0000000..d0f83fb --- /dev/null +++ b/teams/GoToTheDoor/utils.mbt @@ -0,0 +1,22 @@ +// 此文件用于存放一些公共函数 + +pub fn min(a : Double, b : Double) -> Double{ + if a < b { + a + } else { + b + } +} + +pub fn max(a : Double, b : Double) -> Double { + if a < b { + b + } else { + a + } +} + +// 可变引用类型,由于不能创建全局的可变量(即在全局中不能用let mut创建变量,因此实现一个可变引用类型代替 +struct Ref[T] { + mut value : T +} \ No newline at end of file diff --git a/teams/GoToTheDoor/wall.mbt b/teams/GoToTheDoor/wall.mbt new file mode 100644 index 0000000..4ade52b --- /dev/null +++ b/teams/GoToTheDoor/wall.mbt @@ -0,0 +1,237 @@ +// 刚体类 + +struct Wall{ + p:Point + size:Size + // attribute存储了wall的函数调用的索引 + attributes:Array[Int] +} + + +// 根据attribute的数值,选择wall函数,假如某个wall类型物体的attribute=[1,2],那么该wall会依次执行f1,f2函数 +pub fn wall_react(self:Wall, map:Map, player:Player) -> Unit{ + for i=0;iwallRender(self) + 2=>level1MoveLeftFast(self, player) + 3=>level1MoveUpSlow(self, player) + 4=>leve1MoveLeftSlow(self) + 5=>level5MoveDownFast_UpSlow(self,player) + 6=>level5MoveDownSlow_UpSlow(self,player) + 7=>level5MoveRightFast1(self,player) + 8=>level5MoveRightFast(self,player) + 9=>level3Wall5(self,player) + 10=>level3Wall2(self,player) + 11=>level3Wall3(self,player) + 12=>level3Wall4(self,player) + 13=>level2MoveRightFast1(self, player) + 14=>level2MoveUpThenRightFast2(self) + 15=>level4MoveUpAndDown1(self) + 16=>level4MoveUpAndDown2(self) + 17=>level4MoveUpAndDown3(self) + 18=>level7Wall3(self,player) + 19=>levelFinal(self,player) + _=>continue + } + } +} + +//渲染函数 +pub fn wallRender(self:Wall) -> Unit { + @wasm4.set_draw_colors(index=1, 2) + let x:Int = self.p.x.to_int() + let y:Int = self.p.y.to_int() + let sizeX:Int = self.size.width.to_int() + let sizeY:Int = self.size.height.to_int() + @wasm4.rect(x, y, sizeX, sizeY) +} + +//墙下降函数 +fn level1MoveLeftFast(self:Wall, player:Player) -> Unit { + if player.obj.p.x <= 80 && self.p.y == 140 { + self.moveleft_to(-15, 2) + } +} + +fn level1MoveUpSlow(self:Wall, player:Player) -> Unit { + if self.p.x <= -15 && self.p.y >= 80 && player.obj.p.x <= 65{ + self.moveup_to(80, 0.2) + } +} + +fn leve1MoveLeftSlow(self:Wall) -> Unit { + if self.p.x <= 65 && self.p.y == 80 { + self.moveleft_to(-60, 0.5) + } +} + +fn level2MoveRightFast1(self:Wall, player:Player) -> Unit { + if player.obj.p.x >= 106 { + self.moveright_to(134, 2) + } +} + +fn level2MoveUpThenRightFast2(self:Wall) -> Unit { + if (self.p.x <= -60 && self.p.y == 80) { + self.p.y = 79 + } + if self.p.y == 79 { + self.moveright_to(75, 0.3) + } +} + +fn level4MoveUpAndDown1(self:Wall) -> Unit { + if self.p.y <= 120 && self.p.x == 20{ + self.movedown_to(120, 0.5) + } + if self.p.y >= 60 && self.p.x == 30{ + self.moveup_to(60, 0.5) + } + if self.p.y == 60 && self.p.x == 30 { + self.p.x = 20 + } + if self.p.y == 120 && self.p.x == 20 { + self.p.x = 30 + } +} +fn level4MoveUpAndDown2(self:Wall) -> Unit { + if self.p.y <= 120 && self.p.x == 50 { + self.movedown_to(120, 0.5) + } + if self.p.y >= 60 && self.p.x == 60 { + self.moveup_to(60, 0.5) + } + if self.p.y == 60 && self.p.x == 60 { + self.p.x = 50 + } + if self.p.y == 120 && self.p.x == 50 { + self.p.x = 60 + } +} +fn level4MoveUpAndDown3(self:Wall) -> Unit { + if self.p.y <= 120 && self.p.x == 110 { + self.movedown_to(120, 0.5) + } + if self.p.y >= 60 && self.p.x == 120 { + self.moveup_to(60, 0.5) + } + if self.p.y == 60 && self.p.x == 120 { + self.p.x = 110 + } + if self.p.y == 120 && self.p.x == 110 { + self.p.x = 120 + } +} +fn level5MoveDownFast_UpSlow(self:Wall, player:Player) -> Unit { + if (player.obj.p.x <= 24 && player.obj.p.x >= 21 || self.p.x == 35) && self.p.x != 37 { + self.movedown_to(170,5) + self.p.x=35 + } + if self.p.y == 170 { + self.p.x = 37 + } + if self.p.y > 60 && self.p.x == 37 { + self.moveup_to(60, 0.5) + } +} + +fn level5MoveDownSlow_UpSlow(self:Wall, player:Player) -> Unit { + if player.obj.p.x <= 72 && player.obj.p.x >= 62 && self.p.x != 63 { + self.movedown_to(130, 0.6) + } + if self.p.y >= 128 { + self.p.x = 63 + } + if self.p.x == 63 { + self.moveup_to(60, 0.15) + } +} + +fn level5MoveRightFast1(self:Wall, player:Player) -> Unit { + if (player.obj.p.x >= 69 && player.obj.p.y >= 105 || self.p.y == 121) && self.p.y != 119 && (player.obj.p.x > 124 || player.obj.p.x <= 114) { + self.moveright_to(114, 5) + self.p.y = 121 + } + if self.p.x >= 113 { + self.p.y = 119 + } +} + +fn level5MoveRightFast(self:Wall, player:Player) -> Unit { + if player.obj.p.x >= 100 || self.p.y == 59 { + self.moveright_to(160, 5) + self.p.y = 59 + } +} + +fn level3Wall5(self:Wall, player:Player) -> Unit { + if (player.obj.p.x >= 26 || self.p.x == 44) && self.p.x != 43 { + self.moveup_to(100, 5) + self.p.x = 44 + } + if self.p.y <= 100 { + self.p.x = 43 + } + if self.p.x == 43 { + self.movedown_to(120, 0.2) + } +} + +fn level3Wall2(self:Wall, player:Player) -> Unit{ + if player.obj.p.x >= 72 || self.p.x == 44 { + self.movedown_to(160, 0.5) + self.p.x = 44 + } +} + +fn level3Wall3(self:Wall, player:Player) -> Unit{ + if player.obj.p.x >= 90 { + self.moveup_to(60, 0.5) + } +} + +fn level3Wall4(self:Wall, player:Player) -> Unit{ + if player.obj.p.x >= 120 { + self.moveright_to(135, 5) + } +} + +fn level7Wall3(self:Wall, player:Player)->Unit { + if player.obj.p.x >= 95 { + self.movedown_to(250, 0.13) + } +} +fn levelFinal(self:Wall,player:Player)->Unit { + if player.obj.p.x > 80 { + self.moveup_to(120,0.15) + } +} + +//通用移动函数 +fn moveup_to(self:Wall, y:Double, v:Double) -> Unit { + if self.p.y <= y { + return + } + self.p.y -= v +} +fn movedown_to(self:Wall, y:Double, v:Double) -> Unit { + if self.p.y >= y { + return + } + self.p.y += v +} +fn moveleft_to(self:Wall, x:Double, v:Double) -> Unit { + if self.p.x <= x { + return + } + self.p.x -= v +} +fn moveright_to(self:Wall, x:Double, v:Double) -> Unit { + if self.p.x >= x { + return + } + self.p.x += v +} + + +