Kẻ xâm lược không gian JavaScript

Chào mừng đến với phần hai của loạt bài học Javascript của tôi. Trong bài viết này, chúng tôi sẽ tạo trò chơi Space Invaders cổ điển, từng bước một. Hiện tại, chúng tôi đang giữ cho nó thực sự đơn giản - không có khuôn khổ, chỉ có JavaScript và HTML thô. Đây là một ảnh chụp màn hình về những gì chúng ta sẽ thực hiện. Nhấp vào nó để thử nó trong trình duyệt của bạn.  

Kẻ xâm lược không gian JavaScript

Loạt bài Tìm hiểu JavaScript

Đây là phần hai của loạt bài Tìm hiểu JavaScript của tôi

Tìm hiểu JavaScript Phần 1 - Tạo  StarField
Học JavaScript Phần 2 - Kẻ xâm lược không gian
Học JavaScript Phần 3 - AngularJS và Langton's Ant

Loạt bài này nói về việc học JavaScript và ngăn xếp công nghệ HTML5 bằng cách thực hành các dự án.  

Bước 1 - Cấu trúc thư mục

Khi chúng ta bắt đầu phát triển JavaScript từ đầu, hãy nói ngắn gọn về cấu trúc thư mục cho một trang web điển hình. Đây là những gì chúng tôi thường thiết lập.  

kẻ xâm lược không gian
- js
- css
- hình ảnh
- lib

Đó là khá nạc và tiêu chuẩn. Chúng tôi có thư mục 'js' cho các tệp JavaScript của mình, thư mục 'css' cho các biểu định kiểu xếp tầng, thư mục 'lib' cho các thư viện của bên thứ ba như bootstrap và thư mục 'img' cho hình ảnh

Đặt cấu trúc thư mục lại với nhau như được hiển thị - chúng tôi sẽ sử dụng cùng một bố cục trong tương lai

Bước 2 - HTML

Giống như trong phần hướng dẫn trước, chúng ta sẽ có một trang web rất đơn giản cho trò chơi của mình - chủ yếu những gì nó sẽ làm là bao gồm một số JavaScript và bắt đầu chạy trò chơi

Đây là cách chúng ta sẽ bắt đầu.  

HTML

<!DOCTYPE html>
<html>
	<head>
		<title>Space Invaders</title>
		<link rel="stylesheet" type="text/css" href="css/core.css">
		<link rel="stylesheet" type="text/css" href="css/typeography.css">
		<style>
	
			/* Styling needed for a fullscreen canvas and no scrollbars. */
			body, html { 
		    width: 100%;
		    height: 100%;
		    margin: 0;
		    padding: 0;
		    overflow: hidden;
			}
 
			/* Here's where we'll put Space Invader styles.. */
		</style>
	</head>
	<body>
		<!-- this is where the Space Invaders HTML will go.. */ -->
		<script src="js/starfield.js"></script>
		<script src="js/spaceinvaders.js"></script>
		<script>
 
			/* And this is where we'll put our JS. */
		</script>
	</body>
</html> 

Chúng tôi bắt đầu với loại tài liệu html - đây là trang HTML5. Sau đó, chúng tôi đặt tiêu đề và bao gồm hai biểu định kiểu. Các stylesheet này mình dùng rất nhiều cho các bài hướng dẫn đơn giản, chúng chỉ dọn dẹp một số style mặc định của trình duyệt, chúng rất đơn giản, bạn có thể lấy tại github. com/dwmkerr/html5base hoặc bạn có thể lấy chúng từ phần tải xuống.  

Tiếp theo, chúng tôi có một đoạn css nhỏ cho nội dung và các phần tử html - những gì chúng tôi đang làm ở đây là đảm bảo rằng chúng tôi sẽ không có bất kỳ thanh cuộn nào, vì trò chơi này sẽ chỉ lấp đầy cửa sổ. Chúng tôi cũng có một trình giữ chỗ cho các kiểu mà chúng tôi sẽ thêm vào sau

Sau đó, có một nhận xét HTML hiển thị nơi chúng tôi sẽ đặt các yếu tố trò chơi

Để kết thúc, chúng tôi đã bao gồm tập lệnh starfield từ lần trước (đây sẽ là nền của trò chơi) và một 'kẻ xâm lược không gian'. js' mà chúng tôi sẽ tạo ngay sau đây. Sau đó, có một khối tập lệnh cho bất kỳ thứ gì khác mà chúng tôi cần. Bây giờ chúng ta tốt để đi

Bước 3 - Nền Starfield

Xem những hướng dẫn này cực kỳ hữu ích như thế nào? . Chúng tôi sẽ bắt đầu bằng cách thêm một trường sao, giống như chúng tôi đã thực hiện trong hướng dẫn trước. (Nếu bạn không làm theo hướng dẫn đó, bạn có thể lấy starfield tại đây github. com/dwmkerr/starfield).  

Chúng tôi sẽ thêm một div sẽ giữ trường sao. Thêm HTML sau vào trang.  

HTML

<!-- this is where the Space Invaders HTML will go..  -->
 
<!-- Here's a starfield for the background. -->
<div id="starfield"></div>

Div này sẽ chứa trường sao. Bây giờ chúng ta có thể tạo kiểu cho nó trong thành phần kiểu của tiêu đề

CSS

 #starfield {
    width:100%;
    height:100%;
    z-index: -1;
    position: absolute;
    left: 0px;
    top: 0px;
} 

Cuối cùng, trong khối tập lệnh, chúng ta thực sự có thể tạo trường sao

JavaScript

/* And this is where we'll put our JS. */
 
//  Create the starfield.
var container = document.getElementById('starfield');
var starfield = new Starfield();
starfield.initialise(container);
starfield.start(); 

Như chúng ta đã xem chi tiết về trường sao trong phần hướng dẫn trước, chúng ta không cần xem lại ở đây

Ở giai đoạn này, chúng ta có một starfield hoạt hình đơn giản. Bây giờ để làm việc trên trò chơi

Kẻ xâm lược không gian JavaScript
 

Bước 4 - Công cụ trò chơi

Bây giờ chúng ta đang đến với những điều thú vị. Chúng ta sẽ cần thực hiện một số điều khác nhau trong trò chơi của mình - hiển thị màn hình chào mừng, hiển thị màn hình khi trò chơi kết thúc, chạy trò chơi, xử lý đầu vào, v.v.

Khi chúng tôi viết mã, điều đầu tiên chúng tôi nên thử và làm là đảm bảo rằng chúng tôi có thể tách trò chơi thành các 'trạng thái' khác nhau và có một công cụ trò chơi đơn giản có thể chuyển đổi từ trạng thái này sang trạng thái khác, ủy quyền đầu vào của người dùng cho . Đó chính xác là những gì chúng ta sẽ làm

Để đơn giản hóa mọi thứ, tôi đang biến đây thành một Công cụ trò chơi Space Invaders, không phải một công cụ trò chơi thông thường, có thể tái sử dụng, điều đó tốt khi chúng tôi đang học, viết lại mã là tốt và thử mọi thứ theo nhiều cách khác nhau cũng tốt

Vì vậy, hãy suy nghĩ về những gì một công cụ trò chơi cần

  1. Chúng ta sẽ có thể có nhiều trạng thái
  2. Chúng ta sẽ có thể di chuyển từ trạng thái này sang trạng thái khác (e. g. màn hình 'chào mừng' đến màn hình 'chơi')
  3. Một trạng thái sẽ có thể tự vẽ
  4. Một trạng thái sẽ có thể tự cập nhật (e. g. trên một số đánh dấu tùy ý, chúng tôi tiến quân xâm lược, v.v.)
  5. Một trạng thái có thể được 'đẩy' - ví dụ: màn hình bị tạm dừng là trạng thái ở trên cùng của bất kỳ trạng thái nào ở bên dưới nó. Bỏ tạm dừng chỉ đơn giản là bật trạng thái
Với những điều này như một số yêu cầu ban đầu, chúng ta có thể bắt tay vào làm việc. Tạo một 'kẻ xâm lược không gian. js' trong thư mục 'js'. Bây giờ hãy tạo một lớp 'trò chơi'

JavaScript

// Creates an instance of the Game class.
function Game() {
 
 // Set the initial config.
 this.config = {
    gameWidth: 400,
    gameHeight: 300,
    fps: 50
};
 
// All state is in the variables below.
this.lives = 3;
this.width = 0;
this.height = 0;
this.gameBound = {left: 0, top: 0, right: 0, bottom: 0};
 
//  The state stack.
this.stateStack = [];
 
//  Input/output
this.pressedKeys = {};
this.gameCanvas =  null;
}

Lớp này cho đến nay chỉ là dữ liệu. Chúng tôi có một số cấu hình (mà chúng tôi sẽ thêm vào). Cấu hình là cài đặt trò chơi - tốc độ di chuyển của những kẻ xâm lược, v.v. Sau đó, trạng thái thực tế của toàn bộ trò chơi sẽ theo sau (kích thước của khung nhìn, v.v.)

Cuối cùng nhưng không kém phần quan trọng, chúng ta có một mảng mà chúng ta sẽ sử dụng làm ngăn xếp cho các trạng thái của trò chơi, cũng như một đối tượng để giữ các phím hiện đang được nhấn và canvas để hiển thị trò chơi

Bây giờ chúng ta có thể tạo một chức năng khởi tạo trò chơi. Tất cả những gì chúng ta cần làm đầu vào là một canvas để hiển thị thành

JavaScript

//  Initialis the Game with a canvas.
Game.prototype.initialise = function(gameCanvas) {
 
    //  Set the game canvas.
    this.gameCanvas = gameCanvas;
 
    //  Set the game width and height.
    this.width = gameCanvas.width;
    this.height = gameCanvas.height;
 
    //  Set the state game bounds.
    this.gameBounds = {
        left: gameCanvas.width / 2 - this.config.gameWidth / 2,
        right: gameCanvas.width / 2 + this.config.gameWidth / 2,
        top: gameCanvas.height / 2 - this.config.gameHeight / 2,
        bottom: gameCanvas.height / 2 + this.config.gameHeight / 2,
    };
};

Trong chức năng khởi tạo, chúng tôi lưu trữ khung vẽ trò chơi (vì chúng tôi sẽ muốn sử dụng nó sau này) và đặt chiều rộng và chiều cao của trò chơi. Chúng tôi cũng tạo ra các 'giới hạn' của trò chơi - coi đây là một hình chữ nhật mà trò chơi được chơi trong đó. Chúng tôi đặt kích thước của trò chơi trong cấu hình, sau đó chúng tôi vẽ đồ thị mọi thứ liên quan đến giới hạn của trò chơi

Phải - lớp trò chơi của chúng ta cần có khả năng trả về trạng thái của nó. Hãy tạo một hàm currentState

JavaScript

//  Returns the current state.
Game.prototype.currentState = function() {
    return this.stateStack.length > 0 ? this.stateStack[this.stateStack.length - 1] : null

Nếu chúng ta có bất kỳ thứ gì trong ngăn xếp (thực tế là một mảng, nhưng các mảng đủ linh hoạt trong JavaScript để sử dụng làm ngăn xếp khi cần), chúng ta sẽ trả về mục trên cùng (i. e. mục cuối cùng trong mảng). Nếu không, chúng tôi trả về null

Chúng tôi có thể nhận được một đối tượng trạng thái, bây giờ chúng tôi muốn có thể chuyển sang trạng thái

JavaScript

Game.prototype.moveToState = function(state) {
 
    //  Are we already in a state?
    if(this.currentState()) {
 
        //  Before we pop the current state, see if the 
        //  state has a leave function. If it does we can call it.
        if(this.currentState().leave) {
           this.currentState().leave(game);
        }
        
        this.stateStack.pop();
    }
    
    //  If there's an enter function for the new state, call it.
    if(state.enter) {
        state.enter(game);
    }
 
    //  Set the current state.
    this.stateStack.push(state);
}; 

Đây là nơi mọi thứ đang trở nên thông minh hơn. Đây là những gì di chuyển đến một trạng thái làm

  1. Nếu chúng tôi đã ở trạng thái, chúng tôi sẽ kiểm tra xem đối tượng trạng thái có chức năng gọi là 'rời khỏi' không. Nếu có, chúng tôi gọi nó là. Điều này có nghĩa là các đối tượng trạng thái của chúng tôi có thể chọn nhận thông báo nếu chúng sắp thoát
  2. Nếu chúng tôi đã ở trong một trạng thái, hãy bật nó ra khỏi ngăn xếp trạng thái
  3. Nếu có một hàm tên là 'enter' cho trạng thái mới, hãy gọi nó là. Điều này có nghĩa là các tiểu bang có thể chọn nhận thông báo nếu chúng sắp được nhập
  4. Bây giờ chúng tôi đẩy trạng thái mới của mình lên ngăn xếp
Vì vậy, điểm mấu chốt ở đây là - moveToState thay thế phần trên cùng của ngăn xếp trạng thái bằng một trạng thái mới - và các trạng thái có thể biết khi nào họ vào hoặc rời.  

Chúng ta có thể sử dụng chính xác các nguyên tắc giống nhau để nhanh chóng kết nối các hàm pushState và popState

JavaScript

________số 8_______

Các hàm này hoạt động với cùng nguyên tắc như hàm

/* And this is where we'll put our JS. */
 
//  Create the starfield.
var container = document.getElementById('starfield');
var starfield = new Starfield();
starfield.initialise(container);
starfield.start(); 
7

Để trò chơi của chúng ta làm được bất cứ điều gì, chúng ta sẽ cần một số loại vòng lặp đang chạy, thông báo cho trạng thái hoạt động rằng nó cần vẽ, v.v. Vì vậy, hãy kết hợp một hàm toàn cầu

/* And this is where we'll put our JS. */
 
//  Create the starfield.
var container = document.getElementById('starfield');
var starfield = new Starfield();
starfield.initialise(container);
starfield.start(); 
8 để thực hiện điều này

JavaScript

// The main loop.
function gameLoop(game) {
    var currentState = game.currentState();
    if(currentState) {
 
        //  Delta t is the time to update/draw.
        var dt = 1 / game.config.fps;
 
        //  Get the drawing context.
        var ctx = game.gameCanvas.getContext("2d");
		
        //  Update if we have an update function. Also draw
        //  if we have a draw function.
        if(currentState.update) {
            currentState.update(game, dt);
        }
        if(currentState.draw) {
            currentState.draw(game, dt, ctx);
        }
    }
} 

Chức năng này là chính

  1. Đầu tiên, lấy trạng thái trò chơi hiện tại
  2. Bây giờ hãy tính xem một 'tích tắc' của vòng lặp mất bao nhiêu thời gian. Đây là một trong FPS - nếu chúng ta lặp lại mười lần mỗi giây, thì mỗi tích tắc là 100 mili giây
  3. Lấy bối cảnh vẽ từ canvas (điều này được giải thích trong Phần 1)
  4. Nếu có một chức năng gọi là 'cập nhật' trong trạng thái, hãy gọi nó, chuyển đối tượng trò chơi và lượng thời gian đã trôi qua
  5. Nếu có một chức năng gọi là 'vẽ' ở trạng thái, hãy gọi nó, chuyển đối tượng trò chơi, lượng thời gian đã trôi qua và bối cảnh vẽ
Bây giờ chúng ta chỉ cần gọi chức năng này trên bộ đếm thời gian. Chúng tôi có thể tạo phương thức 'bắt đầu' trong Trò chơi cho điều đó

<!-- this is where the Space Invaders HTML will go..  -->
 
<!-- Here's a starfield for the background. -->
<div id="starfield"></div>
0

Đến bây giờ với những gì chúng ta biết về các trạng thái, chúng ta có thể thấy điều này diễn ra như thế nào. Chúng ta bắt đầu trò chơi bằng cách chuyển sang một thể hiện mới của lớp '_______3_______9' (mà chúng ta sẽ tạo tiếp theo. ), chúng tôi đặt số mạng thành ba, sau đó đặt hẹn giờ để gọi

/* And this is where we'll put our JS. */
 
//  Create the starfield.
var container = document.getElementById('starfield');
var starfield = new Starfield();
starfield.initialise(container);
starfield.start(); 
8 dựa trên cài đặt cấu hình FPS. Hãy xem Trạng thái Chào mừng trông như thế nào

Bước 5 - Trạng thái Chào mừng

Trạng thái đầu tiên là một trong những trạng thái dễ nhất, bởi vì tất cả những gì nó làm là hiển thị tiêu đề của trò chơi. Chúng tôi bắt đầu bằng cách tạo một lớp cho trạng thái

JavaScript

<!-- this is where the Space Invaders HTML will go..  -->
 
<!-- Here's a starfield for the background. -->
<div id="starfield"></div>
1

Trạng thái chào mừng đơn giản đến mức nó thậm chí không có bất kỳ thành viên dữ liệu nào. Bây giờ chúng ta có thể tạo một chức năng vẽ

JavaScript

<!-- this is where the Space Invaders HTML will go..  -->
 
<!-- Here's a starfield for the background. -->
<div id="starfield"></div>
2

Một lần nữa, chúng ta có thể xem lại Phần 1 để biết thêm chi tiết về bối cảnh canvas, nhưng không có gì phức tạp ở đây - chúng ta xóa bề mặt bản vẽ, viết "Kẻ xâm lược không gian" và yêu cầu người dùng nhấn phím cách

JavaScript

<!-- this is where the Space Invaders HTML will go..  -->
 
<!-- Here's a starfield for the background. -->
<div id="starfield"></div>
3

Bây giờ chúng ta có thể tạo một hàm keyDown cho trạng thái - nếu mã khóa là khoảng trắng, chúng ta chuyển đến LevelIntroState.  

Vấn đề duy nhất ở đây là keyDown không bao giờ được gọi, vì nó không có trong công cụ trò chơi. Đó là thứ chúng ta có thể thêm vào bây giờ

JavaScript

<!-- this is where the Space Invaders HTML will go..  -->
 
<!-- Here's a starfield for the background. -->
<div id="starfield"></div>
4

GameEngine có thể được thông báo rằng một phím đã được nhấn hoặc nhả. Khi điều đó xảy ra, chúng tôi sẽ xem liệu trạng thái hiện tại có chức năng keyDown hoặc keyUp hay không - nếu vậy chúng tôi gọi nó là. Chúng tôi cũng theo dõi từng phím được nhấn trong một đối tượng để nếu người dùng nhấn nhiều phím, trạng thái có thể xem trò chơi. épKeys và xem những gì được nhấn

Mẹo JavaScript. Từ khóa 'xóa' có thể được sử dụng để xóa một thuộc tính khỏi một đối tượng

Chúng tôi đã tạo trạng thái chào mừng và chúng tôi có chức năng bắt đầu trò chơi, vì vậy hãy quay lại chỉ mục và thực sự thêm trò chơi

Đây là HTML (những gì mới được in đậm)

HTML

<!-- this is where the Space Invaders HTML will go..  -->
 
<!-- Here's a starfield for the background. -->
<div id="starfield"></div>
5

Đây là CSS

CSS

<!-- this is where the Space Invaders HTML will go..  -->
 
<!-- Here's a starfield for the background. -->
<div id="starfield"></div>
6

Cuối cùng, đây là JavaScript

JavaScript

<!-- this is where the Space Invaders HTML will go..  -->
 
<!-- Here's a starfield for the background. -->
<div id="starfield"></div>
7

Điều này không phức tạp như nó có vẻ. Chúng tôi tạo đối tượng Trò chơi, khởi tạo nó bằng canvas, bắt đầu trò chơi và cho nó biết khi nhấn phím. Chúng tôi không để cửa sổ xử lý không gian, trái hoặc phải nếu không nó sẽ cố di chuyển khung nhìn xung quanh và chúng tôi không muốn điều đó

Trò chơi của chúng tôi hiện có màn hình chào mừng - chúng tôi đang đến đó

Kẻ xâm lược không gian JavaScript

Bước 6 - Giới thiệu cấp độ

Trạng thái chào mừng rất đơn giản - nó không cần chức năng cập nhật hoặc nhập hoặc thoát. Bây giờ chúng tôi sẽ tạo một trạng thái mà chúng tôi sử dụng để hiển thị đếm ngược ba giây trước khi cấp độ bắt đầu. Một lần nữa, chúng ta có thể tạo một lớp cho trạng thái

JavaScript

<!-- this is where the Space Invaders HTML will go..  -->
 
<!-- Here's a starfield for the background. -->
<div id="starfield"></div>
8

Trạng thái này thực sự có trạng thái của riêng nó, nó biết nó đang đếm ngược ở cấp độ nào và thông báo nó đang hiển thị. Chúng ta có thể tạo một chức năng vẽ tiếp theo

JavaScript

<!-- this is where the Space Invaders HTML will go..  -->
 
<!-- Here's a starfield for the background. -->
<div id="starfield"></div>
9

Điều này không quan trọng - chúng tôi chỉ hiển thị một thông báo có nội dung 'Sẵn sàng trong X' với X là thông báo đếm ngược

Bây giờ chúng ta có thể tạo một chức năng cập nhật

Mẹo chơi. Chức năng cập nhật là gì? . Chúng ta có thể làm điều này trong draw, nhưng draw chỉ nên hiển thị trung thực trạng thái hiện tại không bị ảnh hưởng. Tại sao lại thế này?

Java

 #starfield {
    width:100%;
    height:100%;
    z-index: -1;
    position: absolute;
    left: 0px;
    top: 0px;
} 
0

Nếu chúng tôi không có số đếm ngược, hãy đặt thành ba (giây). Bây giờ hãy xóa thời gian đã trôi qua (dt tính bằng giây). Mỗi khi số đếm ngược xuống dưới 2 hoặc 1, chúng tôi có thể cập nhật thông báo đếm ngược. Khi nó về 0, chúng tôi có thể chuyển sang Trạng thái chơi - trò chơi thực tế, vượt qua cấp độ mà chúng tôi được thông báo rằng chúng tôi đang đếm ngược

Thế là xong - trạng thái giới thiệu cấp độ đã xong. Vì chúng ta đã chuyển sang nó khi nhấn phím cách ở trạng thái chào mừng, chúng ta có thể chạy lên trang, nhấn phím cách và xem nó hoạt động

Kẻ xâm lược không gian JavaScript

Bước 7 - Trạng thái Play

Đây là cái lớn. Trạng thái chơi biết nó ở cấp độ nào khi nó được tạo và đó là về nó. Chúng tôi phải đảm bảo rằng chúng tôi tạo ra những kẻ xâm lược, định vị chúng, tạo con tàu, định vị nó, phản ứng với chuyển động của chuột, phản ứng với thời gian trôi qua, xử lý bom từ những kẻ xâm lược, tên lửa từ con tàu và điểm số. Nhưng này - đây là JavaScript và kết hợp mọi thứ lại với nhau một cách nhanh chóng là một trong những điều mà ngôn ngữ này giỏi

Đầu tiên - lời nói dối. Khi chúng tôi tạo trạng thái trò chơi, tôi không hiển thị nhiều thuộc tính trong cấu hình Trò chơi. Chúng được sử dụng để điều chỉnh tốc độ mọi thứ di chuyển, tăng tốc hoặc thay đổi, v.v. Nó không cần thiết vào thời điểm đó nhưng bây giờ chúng ta nên xem xét, bởi vì từ hàm tạo Play State, chúng ta có thể thấy rằng chúng ta lấy một bản sao của cấu hình Trò chơi vì chúng ta sử dụng nó quá nhiều

JavaScript

 #starfield {
    width:100%;
    height:100%;
    z-index: -1;
    position: absolute;
    left: 0px;
    top: 0px;
} 
1

Trình tạo thực tế không quá tệ - chúng tôi lấy một bản sao của tham chiếu cấu hình trò chơi, đặt vận tốc hiện tại của những kẻ xâm lược, khoảng cách rơi hiện tại (đó là khoảng cách chúng đã di chuyển xuống dưới khi chạm vào mép màn hình),

Để tham khảo, đây là cấu hình trò chơi thực tế - chúng ta sẽ xem phần lớn cấu hình đó dùng để làm gì khi chúng ta xem qua, nhưng về cơ bản, chúng ta có thể điều chỉnh các khía cạnh về cách trò chơi chạy với chúng.  

JavaScript

 #starfield {
    width:100%;
    height:100%;
    z-index: -1;
    position: absolute;
    left: 0px;
    top: 0px;
} 
2

Chúng ta sẽ đối phó với một con tàu, tên lửa, bom và quân xâm lược. Đến từ một nền tảng tĩnh, điều này khiến tôi muốn tạo kiểu cho chúng, vì vậy đó là những gì tôi sẽ tạo

JavaScript

 #starfield {
    width:100%;
    height:100%;
    z-index: -1;
    position: absolute;
    left: 0px;
    top: 0px;
} 
3

Vì vậy, mỗi thực thể có một vị trí và những thực thể lớn hơn có kích thước. Kẻ xâm lược cũng biết thứ hạng và tệp của nó (nó ở đâu trong lưới)

Bây giờ chúng ta sẽ đi vào chức năng lớn đầu tiên của trạng thái, nhập. Điều này được gọi khi chúng ta bắt đầu mỗi cấp độ

JavaScript

 #starfield {
    width:100%;
    height:100%;
    z-index: -1;
    position: absolute;
    left: 0px;
    top: 0px;
} 
4

Chúng tôi tạo con tàu ở giữa dưới cùng của giới hạn trò chơi

Mã bên dưới trông có vẻ phức tạp nhưng không quá nhiều - nó đảm bảo những thứ như tốc độ của kẻ xâm lược và tốc độ ném bom sẽ nhanh hơn một chút ở mỗi cấp độ, nhưng chỉ có vậy.  

JavaScript

 #starfield {
    width:100%;
    height:100%;
    z-index: -1;
    position: absolute;
    left: 0px;
    top: 0px;
} 
5

Trò chơi thực sự có cấu hình rất cao vì mã như thế này - nó phải như vậy để tôi có thể tìm thấy các giá trị và hệ số hợp lý để có được cảm giác tốt và tăng độ khó khi các cấp độ tăng dần

JavaScript

 #starfield {
    width:100%;
    height:100%;
    z-index: -1;
    position: absolute;
    left: 0px;
    top: 0px;
} 
6

Chúng tôi hoàn thành chức năng nhập bằng cách tạo một kẻ xâm lược ở mỗi cấp bậc và tệp. Có một số số học để định vị và sắp xếp chúng một cách độc đáo. Chúng tôi cũng lưu trữ vận tốc hiện tại của những kẻ xâm lược. Ngoài ra còn có một 'vận tốc tiếp theo' - chúng tôi sử dụng vận tốc đó khi chúng tôi di chuyển chúng xuống dưới và cần quyết định nơi sẽ di chuyển chúng sau đó

Bây giờ để cập nhật. Đây là nơi tất cả trạng thái cho trạng thái được cập nhật

JavaScript

 #starfield {
    width:100%;
    height:100%;
    z-index: -1;
    position: absolute;
    left: 0px;
    top: 0px;
} 
7

Điều đầu tiên chúng ta làm là xem các phím trái hay phải được nhấn. Nếu vậy, chúng tôi huých con tàu. Nếu dấu cách được nhấn, chúng tôi gọi chức năng fireRocket, chúng tôi sẽ đề cập đến chức năng này sau. Chúng tôi cũng đảm bảo rằng chúng tôi không bao giờ di chuyển con tàu qua giới hạn trò chơi.  

Bây giờ chúng ta có thể di chuyển từng quả bom xuống dưới (trừ khi nó vượt quá giới hạn, trong trường hợp đó chúng ta sẽ loại bỏ nó). Chúng tôi cũng có thể di chuyển từng tên lửa lên trên (một lần nữa, trừ khi nó nằm ngoài giới hạn, khi chúng tôi có thể loại bỏ nó)

JavaScript

 #starfield {
    width:100%;
    height:100%;
    z-index: -1;
    position: absolute;
    left: 0px;
    top: 0px;
} 
8

Vì vậy, chúng tôi đã xử lý chuyển động của tàu và chuyển động của bom và tên lửa

Bây giờ đến phần thực sự xấu xí - di chuyển những kẻ xâm lược

JavaScript

 #starfield {
    width:100%;
    height:100%;
    z-index: -1;
    position: absolute;
    left: 0px;
    top: 0px;
} 
9

Tôi xin lỗi. Điều này thực sự khá xấu xí và tôi chắc chắn rằng nó có thể được thực hiện tốt hơn. Chúng tôi di chuyển từng kẻ xâm lược theo vận tốc hiện tại, kiểm tra xem chúng tôi đã chạm vào giới hạn bên trái, bên phải hay dưới cùng. Nếu nó ở bên trái hoặc bên phải, chúng tôi bắt đầu di chuyển những kẻ xâm lược xuống dưới và cho chúng biết nơi di chuyển sau đó. Nếu họ chạm đáy chúng ta sẽ chết. Điều này có vẻ phức tạp nhưng không thực sự, nó chỉ là khó sử dụng. Nhưng tôi chắc chắn rằng nó có thể được thực hiện sạch sẽ hơn

Bây giờ chúng ta có thể thực hiện một số phát hiện va chạm lỗi thời

JavaScript

/* And this is where we'll put our JS. */
 
//  Create the starfield.
var container = document.getElementById('starfield');
var starfield = new Starfield();
starfield.initialise(container);
starfield.start(); 
0

Chúng tôi đi qua từng kẻ xâm lược và xem liệu nó có bị trúng tên lửa hay không. Nếu vậy, chúng tôi loại bỏ tên lửa và kẻ xâm lược sau đó cập nhật điểm số

Vì chúng tôi đã hơi tàn nhẫn với những kẻ xâm lược ở đó, tiếp theo chúng tôi sẽ tìm từng kẻ xâm lược cấp cao nhất và cho nó cơ hội thả một quả bom

JavaScript

/* And this is where we'll put our JS. */
 
//  Create the starfield.
var container = document.getElementById('starfield');
var starfield = new Starfield();
starfield.initialise(container);
starfield.start(); 
1

Một lần nữa, cài đặt trò chơi xuất hiện ở đây khi tỷ lệ bom rơi tăng theo từng cấp độ

Chúng tôi đã kiểm tra tên lửa và quân xâm lược, bây giờ chúng tôi có thể kiểm tra bom và con tàu

/* And this is where we'll put our JS. */
 
//  Create the starfield.
var container = document.getElementById('starfield');
var starfield = new Starfield();
starfield.initialise(container);
starfield.start(); 
2

Và trong khi chúng ta đang ở đó - hãy đảm bảo rằng nếu kẻ xâm lược chạm vào con tàu thì trò chơi cũng kết thúc

JavaScript

/* And this is where we'll put our JS. */
 
//  Create the starfield.
var container = document.getElementById('starfield');
var starfield = new Starfield();
starfield.initialise(container);
starfield.start(); 
3

Mẹo lập trình. Trong mã này, tôi liên tục lặp qua các bộ. Nó có thể được cải thiện rất nhiều bằng cách gây nhiễu nhiều logic hơn vào ít vòng lặp hơn (điều này được gọi là gây nhiễu vòng lặp) nhưng nó sẽ khiến hướng dẫn khó đọc hơn. Nhưng hãy luôn nghi ngờ về mã như trên - với số lượng lớn kẻ xâm lược hoặc bom, chúng tôi lặp lại quá nhiều lần. Luôn để mắt đến vòng lặp dư thừa.  

Chúng ta sắp hoàn thành, việc cuối cùng là xem chúng ta hết mạng và kết thúc trò chơi nếu có, hoặc xem chúng ta đã hết quân xâm lược và đếm ngược cấp độ tiếp theo nếu có

JavaScript

/* And this is where we'll put our JS. */
 
//  Create the starfield.
var container = document.getElementById('starfield');
var starfield = new Starfield();
starfield.initialise(container);
starfield.start(); 
4

Đó là chức năng cập nhật của chúng tôi. Tôi đã hứa tôi cũng sẽ hiển thị chức năng 'fireRocket'

JavaScript

/* And this is where we'll put our JS. */
 
//  Create the starfield.
var container = document.getElementById('starfield');
var starfield = new Starfield();
starfield.initialise(container);
starfield.start(); 
5

Ngạc nhiên một cách đáng ngạc nhiên - chúng tôi cần đảm bảo rằng người dùng không thể chỉ giữ phím cách và bắn bao nhiêu tên lửa tùy thích, vì vậy chúng tôi giới hạn tốc độ bắn trong chức năng này

OK, vậy là chúng ta có Space Invaders, nhưng chỉ là một hệ thống trong bộ nhớ, bây giờ chúng ta cần kết xuất nó. Vì chúng ta chỉ đang lặp qua các thực thể trò chơi và vẽ các nguyên mẫu, nên tôi sẽ không xem xét từng bước một

JavaScript

/* And this is where we'll put our JS. */
 
//  Create the starfield.
var container = document.getElementById('starfield');
var starfield = new Starfield();
starfield.initialise(container);
starfield.start(); 
6

Bây giờ chúng tôi có phần cốt lõi của trò chơi đang hoạt động;

Kẻ xâm lược không gian JavaScript

Bước 8 - Nội dung khác   

Có một vài bit và mảnh mà chúng ta không cần phải đi sâu vào. Có trạng thái kết thúc trò chơi và trạng thái tạm dừng, cũng có một số mã để phát âm thanh, nhưng chúng tôi đã thực sự nhìn thấy cốt lõi của những gì đang diễn ra - thêm nữa chắc chắn sẽ là quá mức cần thiết.  

Mã này có trên GitHub - rẽ nhánh, chơi với nó và tận hưởng niềm vui. Trong hướng dẫn tiếp theo, chúng ta sẽ làm việc với canvas nhưng cũng giới thiệu thêm một số phần tử HTML và sử dụng khung đầu tiên của chúng ta - AngularJS

Như mọi khi, câu hỏi và ý kiến ​​​​được chào đón nhất.  

Giấy phép

Bài viết này, cùng với bất kỳ mã nguồn và tệp liên quan nào, được cấp phép theo Giấy phép Mở Dự án Mã (CPOL)

Tôi có thể tạo trò chơi độc lập bằng JavaScript không?

Có. JavaScript là ngôn ngữ tuyệt vời để phát triển trò chơi, tùy thuộc vào loại trò chơi bạn muốn tạo . JavaScript là tốt nhất cho các trò chơi dựa trên web và di động. Đây cũng là một ngôn ngữ tuyệt vời cho trẻ em học vì nó thường dễ hiểu và có nhiều tài nguyên trực tuyến dành cho các lập trình viên.

Space Invaders có phải là mã nguồn mở không?

Invaders là một trò chơi arcade đầu cuối mã nguồn mở có âm thanh, dựa trên trò chơi arcade cổ điển "Space Invaders".

Làm thế nào để chơi Kẻ xâm lược không gian?

Luật chơi . Người chơi điều khiển khẩu pháo ở cuối màn hình, khẩu pháo này chỉ có thể di chuyển theo chiều ngang . Người ngoài hành tinh di chuyển theo cả chiều ngang và chiều dọc (tiếp cận pháo). Pháo có thể được điều khiển để bắn tia laze để tiêu diệt người ngoài hành tinh, trong khi người ngoài hành tinh sẽ bắn ngẫu nhiên về phía pháo.

Space Invaders có bao giờ kết thúc?

Người ngoài hành tinh bắt đầu bằng năm hàng mười một người di chuyển sang trái và phải theo nhóm, di chuyển xuống dưới mỗi khi họ đến một cạnh màn hình. Mục tiêu là loại bỏ tất cả người ngoài hành tinh bằng cách bắn chúng. Trong khi người chơi có ba mạng, trò chơi sẽ kết thúc ngay lập tức nếu những kẻ xâm lược đến cuối màn hình .