JavaScript是最好的语言之一,尤其是在前端开发中。在本文中,您将找到7个为初学者提供免费源代码的最佳javascript项目。
手把手教你7个有趣的JavaScript 项目-上「附源码」(本篇)
1.使用JavaScript创建待办事项列表应用如果您是javascript语言的初学者,则待办事项列表应用程序是最好的和最容易的应用程序之一,如果您使用HTML CSS和一点点的javascript,则可以创建此简单的待办事项列表应用程序,您将找到源代码这个js项目的底部。
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>创建待办事项列表应用</title>
<style type="text/css">
$primary: #313e50;
$grey: #cdcdcd;
$secondary: #1dd2af;
%reset {
margin: 0;
padding: 0;
border: none;
outline: none;
background: transparent;
}
%transition {
transition: all 0.2s ease;
-webkit-transition: all 0.2s ease;
}
body {
background: #f1f1f1;
margin-top: 2rem;
}
/*PEN STYLES*/
.tasker {
max-width: 400px;
margin: 0 auto;
.error {
display: none;
background: rgba(237, 28, 36, 0.7);
color: #fff;
padding: 14px;
margin-bottom: 10px;
border-radius: 5px;
text-align: center;
}
ul {
@extend %reset;
background: #fff;
}
li,
.error,
button,
input {
@extend %reset;
font: 18px/1.25em Helvetica, Arial, Sans-serif;
}
}
.tasker-header {
display: inline-flex;
background: $primary;
justify-content: space-between;
width: 100%;
input,
button {
color: #fff;
box-sizing: border-box;
font-size: 1.25em;
padding: 14px;
}
input {
flex-grow: 2;
}
button {
@extend %transition;
background: $secondary;
border-left: 1px solid ($secondary * 1.05);
&:hover {
background: $secondary * 1.1;
}
}
}
.tasker-body {
.task {
display: block;
position: relative;
padding: 14px 40px 14px 14px;
border-bottom: 1px solid rgba(0, 0, 0, 0.1);
&:last-child {
border-bottom: none;
}
&:hover > button {
opacity: 1;
}
&.completed {
color: $grey;
text-decoration: line-through;
}
input {
margin-right: 10px;
}
button {
@extend %transition;
color: $grey;
margin: 14px;
position: absolute;
top: 0;
right: 0;
opacity: 0;
&:hover {
color: #ed1c24;
}
}
}
}
</style>
</head>
<body>
<!--PEN CODE-->
<div id="tasker" class="tasker">
<div id="error" class="error">Please enter a task</div>
<div id="tasker-header" class="tasker-header">
<input type="text" id="input-task" placeholder="Enter a task">
<button id="add-task-btn"><i class="fa fa-fw fa-plus"></i>
</button>
</div>
<div class="tasker-body">
<ul id="tasks"></ul>
</div>
</div>
<!--END PEN CODE-->
<script type="text/javascript">
(function() {
'use strict';
var tasker = {
init: function() {
this.cacheDom();
this.bindEvents();
this.evalTasklist();
},
cacheDom: function() {
this.taskInput = document.getElementById("input-task");
this.addBtn = document.getElementById("add-task-btn");
this.tasklist = document.getElementById("tasks");
this.tasklistChildren = this.tasklist.children;
this.errorMessage = document.getElementById("error");
},
bindEvents: function() {
this.addBtn.onclick = this.addTask.bind(this);
this.taskInput.onkeypress = this.enterKey.bind(this);
},
evalTasklist: function() {
var i, chkBox, delBtn;
//BIND CLICK EVENTS TO ELEMENTS
for (i = 0; i < this.tasklistChildren.length; i = 1) {
//ADD CLICK EVENT TO CHECKBOXES
chkBox = this.tasklistChildren[i].getElementsByTagName("input")[0];
chkBox.onclick = this.completeTask.bind(this, this.tasklistChildren[i], chkBox);
//ADD CLICK EVENT TO DELETE BUTTON
delBtn = this.tasklistChildren[i].getElementsByTagName("button")[0];
delBtn.onclick = this.delTask.bind(this, i);
}
},
render: function() {
var taskLi, taskChkbx, taskVal, taskBtn, taskTrsh;
//BUILD HTML
taskLi = document.createElement("li");
taskLi.setAttribute("class", "task");
//CHECKBOX
taskChkbx = document.createElement("input");
taskChkbx.setAttribute("type", "checkbox");
//USER TASK
taskVal = document.createTextNode(this.taskInput.value);
//DELETE BUTTON
taskBtn = document.createElement("button");
//TRASH ICON
taskTrsh = document.createElement("i");
taskTrsh.setAttribute("class", "fa fa-trash");
//INSTERT TRASH CAN INTO BUTTON
taskBtn.appendChild(taskTrsh);
//APPEND ELEMENTS TO TASKLI
taskLi.appendChild(taskChkbx);
taskLi.appendChild(taskVal);
taskLi.appendChild(taskBtn);
//ADD TASK TO TASK LIST
this.tasklist.appendChild(taskLi);
},
completeTask: function(i, chkBox) {
if (chkBox.checked) {
i.className = "task completed";
} else {
this.incompleteTask(i);
}
},
incompleteTask: function(i) {
i.className = "task";
},
enterKey: function(event) {
if (event.keyCode === 13 || event.which === 13) {
this.addTask();
}
},
addTask: function() {
var value = this.taskInput.value;
this.errorMessage.style.display = "none";
if (value === "") {
this.error();
} else {
this.render();
this.taskInput.value = "";
this.evalTasklist();
}
},
delTask: function(i) {
this.tasklist.children[i].remove();
this.evalTasklist();
},
error: function() {
this.errorMessage.style.display = "block";
}
};
tasker.init();
}());
</script>
</body>
</html>
2.使用JavaScript和CSS创建垂直时间轴(里程碑)
您可以使用javascript初学者创建的第二个小项目是时间轴,许多现代网站都使用该时间轴使网站更具交互性和动态性。
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>CSS创建垂直时间轴(里程碑)</title>
<style type="text/css">
*,
*::before,
*::after {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font: normal 16px/1.5 "Helvetica Neue", sans-serif;
background: #456990;
color: #fff;
overflow-x: hidden;
padding-bottom: 50px;
} /* INTRO SECTION
–––––––––––––––––––––––––––––––––––––––––––––––––– */
.intro {
background: #F45B69;
padding: 100px 0;
}
.container {
width: 90%;
max-width: 1200px;
margin: 0 auto;
text-align: center;
}
h1 {
font-size: 2.5rem;
}
/* TIMELINE
–––––––––––––––––––––––––––––––––––––––––––––––––– */
.timeline ul {
background: #456990;
padding: 50px 0;
}
.timeline ul li {
list-style-type: none;
position: relative;
width: 6px;
margin: 0 auto;
padding-top: 50px;
background: #fff;
}
.timeline ul li::after {
content: '';
position: absolute;
left: 50%;
bottom: 0;
transform: translateX(-50%);
width: 30px;
height: 30px;
border-radius: 50%;
background: inherit;
}
.timeline ul li div {
position: relative;
bottom: 0;
width: 400px;
padding: 15px;
background: #F45B69;
}
.timeline ul li div::before {
content: '';
position: absolute;
bottom: 7px;
width: 0;
height: 0;
border-style: solid;
}
.timeline ul li:nth-child(odd) div {
left: 45px;
}
.timeline ul li:nth-child(odd) div::before {
left: -15px;
border-width: 8px 16px 8px 0;
border-color: transparent #F45B69 transparent transparent;
}
.timeline ul li:nth-child(even) div {
left: -439px;
}
.timeline ul li:nth-child(even) div::before {
right: -15px;
border-width: 8px 0 8px 16px;
border-color: transparent transparent transparent #F45B69;
}
time {
display: block;
font-size: 1.2rem;
font-weight: bold;
margin-bottom: 8px;
}
/* EFFECTS
–––––––––––––––––––––––––––––––––––––––––––––––––– */
.timeline ul li::after {
transition: background .5s ease-in-out;
}
.timeline ul li.in-view::after {
background: #F45B69;
}
.timeline ul li div {
visibility: hidden;
opacity: 0;
transition: all .5s ease-in-out;
}
.timeline ul li:nth-child(odd) div {
transform: translate3d(200px, 0, 0);
}
.timeline ul li:nth-child(even) div {
transform: translate3d(-200px, 0, 0);
}
.timeline ul li.in-view div {
transform: none;
visibility: visible;
opacity: 1;
}
/* GENERAL MEDIA QUERIES
–––––––––––––––––––––––––––––––––––––––––––––––––– */
@media screen and (max-width: 900px) {
.timeline ul li div {
width: 250px;
}
.timeline ul li:nth-child(even) div {
left: -289px;
/*250 45-6*/
}
}
@media screen and (max-width: 600px) {
.timeline ul li {
margin-left: 20px;
}
.timeline ul li div {
width: calc(100vw - 91px);
}
.timeline ul li:nth-child(even) div {
left: 45px;
}
.timeline ul li:nth-child(even) div::before {
left: -15px;
border-width: 8px 16px 8px 0;
border-color: transparent #F45B69 transparent transparent;
}
}
</style>
</head>
<body>
<section class="intro">
<div class="container">
<h1>Vertical Timeline ↓</h1>
</div>
</section>
<section class="timeline">
<ul>
<li>
<div>
<time>1934</time> demo1
</div>
</li>
<li>
<div>
<time>1937</time> demo1
</div>
</li>
<li>
<div>
<time>1940</time> demo1
</div>
</li>
<li>
<div>
<time>1943</time> demo1
</div>
</li>
<li>
<div>
<time>1946</time> demo1
</div>
</li>
<li>
<div>
<time>1956</time> demo1
</div>
</li>
<li>
<div>
<time>1957</time> demo1
</div>
</li>
<li>
<div>
<time>1967</time>demo1
</div>
</li>
<li>
<div>
<time>1977</time> demo1
</div>
</li>
<li>
<div>
<time>1985</time> demo1
</div>
</li>
<li>
<div>
<time>2000</time> demo1
</div>
</li>
<li>
<div>
<time>2005</time> demo1
</div>
</li>
</ul>
</section>
<script type="text/javascript">
(function() {
'use strict';
// define variables
var items = document.querySelectorAll(".timeline li");
// check if an element is in viewport
// http://stackoverflow.com/questions/123999/how-to-tell-if-a-dom-element-is-visible-in-the-current-viewport
function isElementInViewport(el) {
var rect = el.getBoundingClientRect();
return (
rect.top >= 0 &&
rect.left >= 0 &&
rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
rect.right <= (window.innerWidth || document.documentElement.clientWidth)
);
}
function callbackFunc() {
for (var i = 0; i < items.length; i ) {
if (isElementInViewport(items[i])) {
items[i].classList.add("in-view");
}
}
}
// listen for events
window.addEventListener("load", callbackFunc);
window.addEventListener("resize", callbackFunc);
window.addEventListener("scroll", callbackFunc);
})();
</script>
</body>
</html>
3.用JavaScript构建一个简单的井字游戏
如果您想构建简单而有趣的东西来练习JavaScript知识,那么使用HTML CSS和JS创建TIC TAC TOE游戏对您来说是个不错的选择,该游戏虽然简单但并不容易,因此您需要专注于该项目的逻辑方面,因为它是该项目最具挑战性的部分。
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>FreeCodeCamp: Tictactoe</title>
<style type="text/css">
@import url(https://fonts.googleapis.com/css?family=Yesteryear);
$app-background-color : #508ABB;
$app-row-height : 100%;
$winAnimStartColor : cyan;
$winAnimEndColor : #508ABB;
// html, body, div, span, a, li, td, th {
// font-family: 'Lato', sans-serif;
// font-weight: 300;
//
// }
@-webkit-keyframes winAnim{
0% {
background-color: $winAnimStartColor;
}
100% {
background-color: $winAnimEndColor;
}
}
@-moz-keyframes winAnim{
0% {
background-color: $winAnimStartColor;
}
100% {
background-color: $winAnimEndColor;
}
}
@-o-keyframes winAnim {
0% {
background-color: $winAnimStartColor;
}
100% {
background-color: $winAnimEndColor;
}
}
@keyframes winAnim {
0% {
background-color: $winAnimStartColor;
}
100% {
background-color: $winAnimEndColor;
}
}
@keyframes winAnim {
0% {
background-color: $winAnimStartColor;
}
100% {
background-color: $winAnimEndColor;
}
}
*{
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
outline-style:none;/*IE*/
}
.center-box{
margin : auto;
position: absolute;
top : 0;
right : 0;
bottom : 0;
left : 0;
}
html,body{
//background-image: linear-gradient(to bottom,#dddbd1,#d2dbdc);
background-color: #d2dbdc;
height : 100%;
width : 100%;
}
.app{
@extend .center-box;
width : 80%;
height : 70%;
max-width: 550px;
background-color : $app-background-color;
box-shadow: 0 5px 30px -5px rgba(0,0,0, .85);
border-radius: 10px;
.app-container,
.app-row{
height: $app-row-height;
}
}
.play-box,.symbol-option{
font-family: 'Yesteryear', cursive;
}
.play-box{
border-bottom : 2px solid #fff;
border-right : 2px solid #fff;
height : $app-row-height / 3;
cursor: pointer;
position: relative;
&.last-right{
border-right : none;
}
&.last-bottom{
border-bottom : none;
}
&.win {
-webkit-animation: winAnim .2s ease-out infinite;
-moz-animation: winAnim .2s ease-out infinite;
-o-animation: winAnim .2s ease-out infinite;
animation: winAnim .2s ease-out infinite;
animation : winAnim .5s infinite;
}
.symbol{
@extend .center-box;
width: 50%;
height : 50px;
text-align: center;
line-height : 50px;
font-size: 35px;
color : white;
}
}
.modal-content{
.content{
padding : 15px;
text-align: center;
margin : 0;
&.body{
line-height: 2;
}
}
.symbol-options{
width: 200px;
margin-top: 10px;
.symbol-option{
&:first-child{
margin-right: 10px;
}
&:last-child{
margin-left: 10px;
}
}
}
.warning-hr{
margin: 0;
}
}
</style>
</head>
<body>
<div class="app">
<div class="container-fluid app-container">
<div class="row app-row">
<div class="col-xs-4 play-box" id="0">
<div class="symbol"></div>
</div>
<div class="col-xs-4 play-box" id="1">
<div class="symbol"></div>
</div>
<div class="col-xs-4 play-box last-right" id="2">
<div class="symbol"></div>
</div>
<div class="col-xs-4 play-box" id="3">
<div class="symbol"></div>
</div>
<div class="col-xs-4 play-box" id="4">
<div class="symbol"></div>
</div>
<div class="col-xs-4 play-box last-right" id="5">
<div class="symbol"></div>
</div>
<div class="col-xs-4 play-box last-bottom" id="6">
<div class="symbol"></div>
</div>
<div class="col-xs-4 play-box last-bottom" id="7">
<div class="symbol"></div>
</div>
<div class="col-xs-4 play-box last-right last-bottom" id="8">
<div class="symbol"></div>
</div>
</div>
</div>
</div>
<div class="modal fade app-modal" tabindex="-1" role="dialog" aria-labelledby="mySmallModalLabel">
<div class="modal-dialog modal-size">
<div class="modal-content">
<h3 class="content heading">Warning!!!</h3>
<hr class="warning-hr">
<div class="content body">
Please save your time and don't even think you're smart. <br><strong><em>I'M SMARTER THAN YOU! HA-HA-HA!!!</em></strong> <br>
Wana try me? Chose : <br>
<div class="center-block symbol-options">
<button class="symbol-option btn btn-default btn-md" data-dismiss="modal">X</button> OR <button class="symbol-option btn btn-default btn-md" data-dismiss="modal">O</button>
</div>
</div>
</div>
</div>
</div>
<script src="../js/bundled/tictactoe.bundled.js">
</script>
</body>
</html>
4.创建一个JavaScript倒数计时器开始停止重置
许多现代网站和博客都使用倒数计时器来显示倒数,例如,我们通过使用倒数计时器来告诉在线商店的访问者,商品价格将在价格上涨后增加销售量。具体时间。
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>CSS创建垂直时间轴(里程碑)</title>
<style type="text/css">
/* Variabes */
$orange: #ffa600;
$grey:#f3f3f3;
$white: #fff;
$base-color:$orange ;
/* Mixin's */
@mixin transition {
-webkit-transition: all 0.5s ease-in-out;
-moz-transition: all 0.5s ease-in-out;
transition: all 0.5s ease-in-out;
}
@mixin corners ($radius) {
-moz-border-radius: $radius;
-webkit-border-radius: $radius;
border-radius: $radius;
-khtml-border-radius: $radius;
}
body {
background:$base-color;
font-family: "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif;
height:100%;
}
.wrapper {
width: 800px;
margin: 30px auto;
color:$white;
text-align:center;
}
h1, h2, h3 {
font-family: 'Roboto', sans-serif;
font-weight: 100;
font-size: 2.6em;
text-transform: uppercase;
}
#seconds, #tens{
font-size:2em;
}
button{
@include corners (5px);
background:$base-color;
color:$white;
border: solid 1px $white;
text-decoration:none;
cursor:pointer;
font-size:1.2em;
padding:18px 10px;
width:180px;
margin: 10px;
outline: none;
&:hover{
@include transition;
background:$white;
border: solid 1px $white;
color:$base-color;
}
}
</style>
</head>
<body>
<div class="wrapper">
<h1>Stopwatch</h1>
<h2>Vanilla JavaScript Stopwatch</h2>
<p><span id="seconds">00</span>:<span id="tens">00</span></p>
<button id="button-start">Start</button>
<button id="button-stop">Stop</button>
<button id="button-reset">Reset</button>
</div>
<script type="text/javascript">
window.onload = function () {
var seconds = 00;
var tens = 00;
var appendTens = document.getElementById("tens")
var appendSeconds = document.getElementById("seconds")
var buttonStart = document.getElementById('button-start');
var buttonStop = document.getElementById('button-stop');
var buttonReset = document.getElementById('button-reset');
var Interval ;
buttonStart.onclick = function() {
clearInterval(Interval);
Interval = setInterval(startTimer, 10);
}
buttonStop.onclick = function() {
clearInterval(Interval);
}
buttonReset.onclick = function() {
clearInterval(Interval);
tens = "00";
seconds = "00";
appendTens.innerHTML = tens;
appendSeconds.innerHTML = seconds;
}
function startTimer () {
tens ;
if(tens < 9){
appendTens.innerHTML = "0" tens;
}
if (tens > 9){
appendTens.innerHTML = tens;
}
if (tens > 99) {
console.log("seconds");
seconds ;
appendSeconds.innerHTML = "0" seconds;
tens = 0;
appendTens.innerHTML = "0" 0;
}
if (seconds > 9){
appendSeconds.innerHTML = seconds;
}
}<script src="../js/bundled/tictactoe.bundled.js">
</script>
}
</script>
</body>
</html>
5.用JavaScript创建一个简单的乒乓球游戏
我可以用JavaScript构建游戏吗?答案是肯定的,使用javascript甚至可以创建复杂的游戏,但是在这种情况下,我们将专注于一个简单的游戏,该游戏可让您练习HTML CSS和javascript技能。
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>使用js调用设备摄像头并实现拍照</title>
<style type="text/css">
body {
text-align: center;
}
</style>
</head>
<body>
<script type="text/javascript">
// Global Variables
var DIRECTION = {
IDLE: 0,
UP: 1,
DOWN: 2,
LEFT: 3,
RIGHT: 4
};
var rounds = [5, 5, 3, 3, 2];
var colors = ['#1abc9c', '#2ecc71', '#3498db', '#e74c3c', '#9b59b6'];
// The ball object (The cube that bounces back and forth)
var Ball = {
new: function (incrementedspeed) {
return {
width: 18,
height: 18,
x: (this.canvas.width / 2) - 9,
y: (this.canvas.height / 2) - 9,
moveX: DIRECTION.IDLE,
moveY: DIRECTION.IDLE,
speed: incrementedSpeed || 9
};
}
};
// The paddle object (The two lines that move up and down)
var Paddle = {
new: function (side) {
return {
width: 18,
height: 70,
x: side === 'left' ? 150 : this.canvas.width - 150,
y: (this.canvas.height / 2) - 35,
score: 0,
move: DIRECTION.IDLE,
speed: 10
};
}
};
var Game = {
initialize: function () {
this.canvas = document.querySelector('canvas');
this.context = this.canvas.getContext('2d');
this.canvas.width = 1400;
this.canvas.height = 1000;
this.canvas.style.width = (this.canvas.width / 2) 'px';
this.canvas.style.height = (this.canvas.height / 2) 'px';
this.player = Paddle.new.call(this, 'left');
this.paddle = Paddle.new.call(this, 'right');
this.ball = Ball.new.call(this);
this.paddle.speed = 8;
this.running = this.over = false;
this.turn = this.paddle;
this.timer = this.round = 0;
this.color = '#2c3e50';
Pong.menu();
Pong.listen();
},
endGameMenu: function (text) {
// Change the canvas font size and color
Pong.context.font = '50px Courier New';
Pong.context.fillStyle = this.color;
// Draw the rectangle behind the 'Press any key to begin' text.
Pong.context.fillRect(
Pong.canvas.width / 2 - 350,
Pong.canvas.height / 2 - 48,
700,
100
);
// Change the canvas color;
Pong.context.fillStyle = '#ffffff';
// Draw the end game menu text ('Game Over' and 'Winner')
Pong.context.fillText(text,
Pong.canvas.width / 2,
Pong.canvas.height / 2 15
);
setTimeout(function () {
Pong = Object.assign({}, Game);
Pong.initialize();
}, 3000);
},
menu: function () {
// Draw all the Pong objects in their current state
Pong.draw();
// Change the canvas font size and color
this.context.font = '50px Courier New';
this.context.fillStyle = this.color;
// Draw the rectangle behind the 'Press any key to begin' text.
this.context.fillRect(
this.canvas.width / 2 - 350,
this.canvas.height / 2 - 48,
700,
100
);
// Change the canvas color;
this.context.fillStyle = '#ffffff';
// Draw the 'press any key to begin' text
this.context.fillText('Press any key to begin',
this.canvas.width / 2,
this.canvas.height / 2 15
);
},
// Update all objects (move the player, paddle, ball, increment the score, etc.)
update: function () {
if (!this.over) {
// If the ball collides with the bound limits - correct the x and y coords.
if (this.ball.x <= 0) Pong._resetTurn.call(this, this.paddle, this.player);
if (this.ball.x >= this.canvas.width - this.ball.width) Pong._resetTurn.call(this, this.player, this.paddle);
if (this.ball.y <= 0) this.ball.moveY = DIRECTION.DOWN;
if (this.ball.y >= this.canvas.height - this.ball.height) this.ball.moveY = DIRECTION.UP;
// Move player if they player.move value was updated by a keyboard event
if (this.player.move === DIRECTION.UP) this.player.y -= this.player.speed;
else if (this.player.move === DIRECTION.DOWN) this.player.y = this.player.speed;
// On new serve (start of each turn) move the ball to the correct side
// and randomize the direction to add some challenge.
if (Pong._turnDelayIsOver.call(this) && this.turn) {
this.ball.moveX = this.turn === this.player ? DIRECTION.LEFT : DIRECTION.RIGHT;
this.ball.moveY = [DIRECTION.UP, DIRECTION.DOWN][Math.round(Math.random())];
this.ball.y = Math.floor(Math.random() * this.canvas.height - 200) 200;
this.turn = null;
}
// If the player collides with the bound limits, update the x and y coords.
if (this.player.y <= 0) this.player.y = 0;
else if (this.player.y >= (this.canvas.height - this.player.height)) this.player.y = (this.canvas.height - this.player.height);
// Move ball in intended direction based on moveY and moveX values
if (this.ball.moveY === DIRECTION.UP) this.ball.y -= (this.ball.speed / 1.5);
else if (this.ball.moveY === DIRECTION.DOWN) this.ball.y = (this.ball.speed / 1.5);
if (this.ball.moveX === DIRECTION.LEFT) this.ball.x -= this.ball.speed;
else if (this.ball.moveX === DIRECTION.RIGHT) this.ball.x = this.ball.speed;
// Handle paddle (AI) UP and DOWN movement
if (this.paddle.y > this.ball.y - (this.paddle.height / 2)) {
if (this.ball.moveX === DIRECTION.RIGHT) this.paddle.y -= this.paddle.speed / 1.5;
else this.paddle.y -= this.paddle.speed / 4;
}
if (this.paddle.y < this.ball.y - (this.paddle.height / 2)) {
if (this.ball.moveX === DIRECTION.RIGHT) this.paddle.y = this.paddle.speed / 1.5;
else this.paddle.y = this.paddle.speed / 4;
}
// Handle paddle (AI) wall collision
if (this.paddle.y >= this.canvas.height - this.paddle.height) this.paddle.y = this.canvas.height - this.paddle.height;
else if (this.paddle.y <= 0) this.paddle.y = 0;
// Handle Player-Ball collisions
if (this.ball.x - this.ball.width <= this.player.x && this.ball.x >= this.player.x - this.player.width) {
if (this.ball.y <= this.player.y this.player.height && this.ball.y this.ball.height >= this.player.y) {
this.ball.x = (this.player.x this.ball.width);
this.ball.moveX = DIRECTION.RIGHT;
beep1.play();
}
}
// Handle paddle-ball collision
if (this.ball.x - this.ball.width <= this.paddle.x && this.ball.x >= this.paddle.x - this.paddle.width) {
if (this.ball.y <= this.paddle.y this.paddle.height && this.ball.y this.ball.height >= this.paddle.y) {
this.ball.x = (this.paddle.x - this.ball.width);
this.ball.moveX = DIRECTION.LEFT;
beep1.play();
}
}
}
// Handle the end of round transition
// Check to see if the player won the round.
if (this.player.score === rounds[this.round]) {
// Check to see if there are any more rounds/levels left and display the victory screen if
// there are not.
if (!rounds[this.round 1]) {
this.over = true;
setTimeout(function () { Pong.endGameMenu('Winner!'); }, 1000);
} else {
// If there is another round, reset all the values and increment the round number.
this.color = this._generateRoundColor();
this.player.score = this.paddle.score = 0;
this.player.speed = 0.5;
this.paddle.speed = 1;
this.ball.speed = 1;
this.round = 1;
beep3.play();
}
}
// Check to see if the paddle/AI has won the round.
else if (this.paddle.score === rounds[this.round]) {
this.over = true;
setTimeout(function () { Pong.endGameMenu('Game Over!'); }, 1000);
}
},
// Draw the objects to the canvas element
draw: function () {
// Clear the Canvas
this.context.clearRect(
0,
0,
this.canvas.width,
this.canvas.height
);
// Set the fill style to black
this.context.fillStyle = this.color;
// Draw the background
this.context.fillRect(
0,
0,
this.canvas.width,
this.canvas.height
);
// Set the fill style to white (For the paddles and the ball)
this.context.fillStyle = '#ffffff';
// Draw the Player
this.context.fillRect(
this.player.x,
this.player.y,
this.player.width,
this.player.height
);
// Draw the Paddle
this.context.fillRect(
this.paddle.x,
this.paddle.y,
this.paddle.width,
this.paddle.height
);
// Draw the Ball
if (Pong._turnDelayIsOver.call(this)) {
this.context.fillRect(
this.ball.x,
this.ball.y,
this.ball.width,
this.ball.height
);
}
// Draw the net (Line in the middle)
this.context.beginPath();
this.context.setLineDash([7, 15]);
this.context.moveTo((this.canvas.width / 2), this.canvas.height - 140);
this.context.lineTo((this.canvas.width / 2), 140);
this.context.lineWidth = 10;
this.context.strokeStyle = '#ffffff';
this.context.stroke();
// Set the default canvas font and align it to the center
this.context.font = '100px Courier New';
this.context.textAlign = 'center';
// Draw the players score (left)
this.context.fillText(
this.player.score.toString(),
(this.canvas.width / 2) - 300,
200
);
// Draw the paddles score (right)
this.context.fillText(
this.paddle.score.toString(),
(this.canvas.width / 2) 300,
200
);
// Change the font size for the center score text
this.context.font = '30px Courier New';
// Draw the winning score (center)
this.context.fillText(
'Round ' (Pong.round 1),
(this.canvas.width / 2),
35
);
// Change the font size for the center score value
this.context.font = '40px Courier';
// Draw the current round number
this.context.fillText(
rounds[Pong.round] ? rounds[Pong.round] : rounds[Pong.round - 1],
(this.canvas.width / 2),
100
);
},
loop: function () {
Pong.update();
Pong.draw();
// If the game is not over, draw the next frame.
if (!Pong.over) requestAnimationFrame(Pong.loop);
},
listen: function () {
document.addEventListener('keydown', function (key) {
// Handle the 'Press any key to begin' function and start the game.
if (Pong.running === false) {
Pong.running = true;
window.requestAnimationFrame(Pong.loop);
}
// Handle up arrow and w key events
if (key.keyCode === 38 || key.keyCode === 87) Pong.player.move = DIRECTION.UP;
// Handle down arrow and s key events
if (key.keyCode === 40 || key.keyCode === 83) Pong.player.move = DIRECTION.DOWN;
});
// Stop the player from moving when there are no keys being pressed.
document.addEventListener('keyup', function (key) { Pong.player.move = DIRECTION.IDLE; });
},
// Reset the ball location, the player turns and set a delay before the next round begins.
_resetTurn: function(victor, loser) {
this.ball = Ball.new.call(this, this.ball.speed);
this.turn = loser;
this.timer = (new Date()).getTime();
victor.score ;
beep2.play();
},
// Wait for a delay to have passed after each turn.
_turnDelayIsOver: function() {
return ((new Date()).getTime() - this.timer >= 1000);
},
// Select a random color as the background of each level/round.
_generateRoundColor: function () {
var newColor = colors[Math.floor(Math.random() * colors.length)];
if (newColor === this.color) return Pong._generateRoundColor();
return newColor;
}
};
var Pong = Object.assign({}, Game);
Pong.initialize();
</script>
</body>
</html>
本篇未完结,请继续看下一篇:
推荐JavaScript经典实例学习资料文章《》
《》
《》
《》
《》
《》
《》
《》
《》
《》
《》
《》
《》
《》
《》
《》
《》
《》
《》
《》
《》
《》
《》
《》
《》
《》
《》
《》
《》
《》
《》
《》
《》
《》
《》
《》
《》
《》
《》
《》
《》
《》
《》
《》
《》
《》
《》
《》
《》
《》
《》
《》
《》
《》
《》
《》
《》
《》
《》
《》
《》
《》
《》
《》
《》
《》
《》
《》
《》
《》
《》
《》
《》
《》
《》
《》
《》
《》
《》
《》
《》
《》
《》
《》
《》
《》
《》
《》
《》
《》
《》
Copyright © 2024 妖气游戏网 www.17u1u.com All Rights Reserved