java开发体系基本:放大招!为系统开发星球大战游戏程序。项目:外星人入侵。

时,我们的系就前进到了定较为完美的品位,当然最好一个练习系统,它不容许和正规的windows或linux相比,但麻雀虽小五腑俱全,我们的体系要会支持用户以该上面开发出众多扑朔迷离而同时幽默的应用程序的,它所显现的成效完全可以称得上是一个鲁棒的操作系统。

 这次小编上传一个嬉戏支付的品类,一方面是自己写及失去会再次好的熟稔这类型,并且将团结的经验可以享者,另一方面,可以被再多之盆友看到,提高自己。

俺们看看第一只好玩的应用程序:不规则窗口。
不少独居特色之应用程序,一挺特点有就是是畸形窗口,奇形怪状的窗体形态确实容易被人耳目一新的感觉,不规则窗口要是管窗体的某某有用透明色来展现,现在咱们尽管来品尝一下,在app.c中落成以下代码:

      
这个戏类利用的凡pygame,这是如出一辙组强大使有趣之模块,可用于管理图形,动画乃至声音,让您能重自在的出复杂的游艺,通过利用pygame来处理在屏幕上制图图像等职责,我们决不考虑多麻烦而艰苦的编程工作,而是以重要放在程序及之高等级逻辑上面。

void main() {
    int win;
    char buf[150*70];
    win = api_openwin(buf, 150, 70, 255, "noterec");
    api_boxfilwin(win, 0, 50, 34, 69, 255);
    api_boxfilwin(win, 115, 50, 149, 69, 255);
    api_boxfilwin(win, 50, 30, 99, 49, 255);
    for (;;) {
        if (api_getkey(1) == 0x1c) {
            break;
        }
    }
    api_closewin(win);
    return;
}

首先步:规划类

  
开发大型项目时候,做好设计还着手编写项目非常关键,规划方可保证我们无偏离轨道,从而提高项目成功之可能。

   
下面 来编排有关游戏《外星人入侵》的讲述,可能里面并未含所有的打细节,但是嗯那个为我们狠清晰的明白怎么样入手开发其

  必威电竞     
在戏耍《外星人入侵》中,玩家操纵着同艘最初出现在屏幕底边中央之飞船。玩家可用箭头键左右动飞船,还可以空格键进行规划。游戏开始经常,一多外星人出现于天,他们以屏幕中为下移动。玩家的职责是射杀这些外星人。玩家将所有的外星人射击干净后,将现出一个初的外星人,他们的动宿舍还快。只要有外星人撞至玩家的飞艇或者到屏幕底边,玩家就损失一所飞船。玩家损失三条飞船后,游戏了。

点代码先创造一个窗体,然后把窗体的若干单有填充成透明色,于是窗体形态变成一个诙谐的非矩形,上面代码完成后,运行起来情况如下:

第二步:安装pygame

      
pygame项目托管在代码分享网址Bitbucket中,要当windows系统中安pygame,则可看网站

https://bitbucket.org/pygame/pygame/downloads/

(在网址中查找合适的次第下载)

必威电竞 1

 

安装程序如下:

pip install pygame-1.9.3-cp36-cp36m-win_amd64.whl

必威电竞 2

 第三步:开始打类

     
首先得创建游戏界面,然后上加飞船图像,飞船添加上,我们务必允许她好左右走,再上加发子弹的效能。

       然后创造外星人,让外星人移动,我们开展射击外星人,然后收游戏。

      
最后咱们得进行记分,提高等级等装置,急需完善娱乐,这样一个嬉戏就是装完。

  
说起来大概,但是做起来麻烦。这三有的,每有都是一个整,而且实现新职能下,必须再次构源代码,一不小心便错,所以得稀上心。

现实的种类实行步骤,我就是于这边不一一讲解了,主要将代码贴出,让大家参考一下

以此是颇具代码的目:

必威电竞 3

 

率先是主程序 alien_invasion.py

必威电竞 4必威电竞 5

import pygame
from pygame.sprite import Group

from settings import Settings
from game_stats import GameStats
from scoreboard import Scoreboard
from button import Button
from ship import Ship
from alien import Alien
import game_functions as gf


def run_game():
    # Initialize pygame, settings, and screen object.
    pygame.init()
    ai_settings = Settings()
    screen = pygame.display.set_mode(
        (ai_settings.screen_width, ai_settings.screen_height))
    pygame.display.set_caption("Alien Invasion")

    #创建play按钮
    play_button = Button(ai_settings,screen,"Play")

    #创建一个用于存储游戏统计信息的实例
    stats = GameStats(ai_settings)
    sb = Scoreboard(ai_settings,screen,stats)

    # Set the background color.
    bg_color = (230, 230, 230)

    # Make a ship.
    ship = Ship(ai_settings, screen)
    # Make a group to store bullets in.
    bullets = Group()
    aliens = Group()

    #创建外星人群
    gf.create_fleet(ai_settings,screen,ship,aliens)

    # Start the main loop for the game.
    while True:
        gf.check_events(ai_settings, screen, stats,sb,play_button,ship,
                        aliens, bullets)

        if stats.game_active:
            ship.update()
            gf.update_bullets(ai_settings,screen,stats,sb,ship,aliens,bullets)
            gf.update_aliens(ai_settings,screen,stats,sb,ship,aliens,bullets)

        gf.update_screen(ai_settings, screen,stats, sb,ship,aliens,
                         bullets,play_button)


run_game()

View Code

下一场是职能函数 game_function.py

必威电竞 6必威电竞 7

import sys
from time import sleep
import pygame

from bullet import Bullet
from alien import Alien
import pygame

def check_keydown_events(event, ai_settings, screen, ship, bullets):
    """Respond to keypresses."""
    if event.key == pygame.K_RIGHT:
        ship.moving_right = True
    elif event.key == pygame.K_LEFT:
        ship.moving_left = True
    elif event.key == pygame.K_SPACE:
        fire_bullet(ai_settings, screen, ship, bullets)


def check_keyup_events(event, ship):
    """Respond to key releases."""
    if event.key == pygame.K_RIGHT:
        ship.moving_right = False
    elif event.key == pygame.K_LEFT:
        ship.moving_left = False


def check_events(ai_settings, screen, stats,sb, play_button,ship,aliens, bullets):
    """Respond to keypresses and mouse events."""
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()
        elif event.type == pygame.KEYDOWN:
            check_keydown_events(event, ai_settings, screen, ship, bullets)
        elif event.type == pygame.KEYUP:
            check_keyup_events(event, ship)
        elif event.type == pygame.MOUSEBUTTONDOWN:
            mouse_x,mouse_y = pygame.mouse.get_pos()
            check_play_button(ai_settings, screen,stats,sb,play_button,
                              ship,aliens,bullets,mouse_x,mouse_y)


def check_play_button(ai_settings,screen,stats,sb,play_button, ship,aliens,bullets,mouse_x,mouse_y):
    """玩家单击play按钮开始新游戏"""
    button_clicked = play_button.rect.collidepoint(mouse_x, mouse_y)
    if button_clicked and not stats.game_active:
        #重置游戏设置
        ai_settings.initialize_dynamic_settings()

        #隐藏光标
        pygame.mouse.set_visible(False)
    if play_button.rect.collidepoint(mouse_x,mouse_y):
        #重置游戏统计信息
        stats.reset_stats()
        stats.game_active = True

        #重置记分牌图像
        sb.prep_score()
        sb.prep_high_score()
        sb.prep_level()
        sb.prep_ships()

        #清空外星人列表和子弹列表
        aliens.empty()
        bullets.empty()

        #创建一群新的外星人,并让其居中
        create_fleet(ai_settings,screen,ship,aliens)
        ship.center_ship()


def fire_bullet(ai_settings, screen, ship, bullets):
    """Fire a bullet, if limit not reached yet."""
    # Create a new bullet, add to bullets group.
    if len(bullets) < ai_settings.bullets_allowed:
        new_bullet = Bullet(ai_settings, screen, ship)
        bullets.add(new_bullet)


def update_screen(ai_settings, screen, stats,sb,ship,
                  aliens,bullets,play_button):
    """Update images on the screen, and flip to the new screen."""
    # Redraw the screen, each pass through the loop.
    screen.fill(ai_settings.bg_color)

    # Redraw all bullets, behind ship and aliens.
    for bullet in bullets.sprites():
        bullet.draw_bullet()
    ship.blitme()
    aliens.draw(screen)

    #显示得分
    sb.show_score()

    #如果游戏处于非活跃状态,就绘制play按钮
    if not stats.game_active:
        play_button.draw_button()


    # Make the most recently drawn screen visible.
    pygame.display.flip()


def update_bullets(ai_settings,screen,stats,sb,ship,aliens,bullets):
    """Update position of bullets, and get rid of old bullets."""
    # Update bullet positions.
    bullets.update()

    # Get rid of bullets that have disappeared.
    for bullet in bullets.copy():
        if bullet.rect.bottom <= 0:
            bullets.remove(bullet)
    check_bullet_alien_collisions(ai_settings,screen,stats,sb,ship,aliens,bullets)

def check_bullet_alien_collisions(ai_settings,screen,stats,sb,ship,aliens,bullets):
    #检查是否有子弹击中了外星人
    #如果是这样样,就删除相应的额子弹和外星人
    collisions = pygame.sprite.groupcollide(bullets,aliens,True,True)

    if collisions:
        for aliens in collisions.values():
            stats.score += ai_settings.alien_points*len(aliens)
            sb.prep_score()
        check_high_score(stats,sb)


    if len(aliens) == 0:
         # If the entire fleet is destroyed, start a new level.
        bullets.empty()
        ai_settings.increase_speed()

        #提高等级
        stats.level +=1
        sb.prep_level()

        create_fleet(ai_settings,screen,ship,aliens)



def get_number_aliens_x(ai_settings,alien_width):
    """计算每行可容纳多少个外星人"""
    available_space_x = ai_settings.screen_width - 2 * alien_width
    number_aliens_x = int(available_space_x / (2 * alien_width))
    return number_aliens_x

def get_number_rows(ai_settings,ship_height,aliens_height):
    """计算屏幕可以容纳多少个外星人"""
    avaliable_space_y = (ai_settings.screen_height -(3*aliens_height)-ship_height)
    number_rows = int(avaliable_space_y /(2*aliens_height))
    return number_rows


def create_alien(ai_settings,screen,aliens,alien_number,row_number):
    """创建一个外星人并将其放在当前列"""
    alien = Alien(ai_settings, screen)
    alien_width= alien.rect.width
    alien.x = alien_width + 2 * alien_width * alien_number
    alien.rect.x = alien.x
    alien.rect.y = alien.rect.height + 2 * alien.rect.height * row_number
    aliens.add(alien)

def create_fleet(ai_settings,screen,ship,aliens):
    """创建外星人群"""
    #创建一个外星人,并计算一行可以容纳多少个外星人,外星人间距为外星人的宽度
    alien = Alien(ai_settings,screen)
    number_aliens_x = get_number_aliens_x(ai_settings,alien.rect.width)
    number_rows = get_number_rows(ai_settings,ship.rect.height,alien.rect.height)

    #创建外星人群
    for row_number in range(number_rows):
        for alien_number in range(number_aliens_x):
            #创建一个外星人并将其加入当前行
             create_alien(ai_settings,screen,aliens,alien_number,row_number)

def check_fleet_edges(ai_settings,aliens):
    """有外星人到达边缘时候采取相应的措施"""
    for alien in aliens.sprites():
        if alien.check_edges():
            change_fleet_direction(ai_settings,aliens)
            break

def change_fleet_direction(ai_settings,aliens):
    """将整群外星人下移,并改变他们的方向"""
    for alien in aliens.sprites():
        alien.rect.y += ai_settings.fleet_drop_speed
    ai_settings.fleet_direction *= -1


def update_aliens(ai_settings,screen,stats,sb,ship,aliens,bullets):
    """检查是否有外星人位于屏幕边缘,更新外星人群中所有外星人的位置"""
    check_fleet_edges(ai_settings,aliens)
    aliens.update()

    #监测外星人和飞船之间的碰撞
    if pygame.sprite.spritecollideany(ship,aliens):
        ship_hit(ai_settings,screen,stats,sb,ship,aliens,bullets)

    #检查是狗友外星人到达屏幕底部
    check_aliens_bottom(ai_settings,screen,stats,sb,ship,aliens,bullets)

def ship_hit(ai_settings,screen,stats,sb,ship,aliens,bullents):
    """响应被外星人撞到的飞船"""

    if stats.ships_left >0:
        # 将shios_left减1
        stats.ships_left -=1

        #更新记分牌
        sb.prep_ships()

    else:
        stats.game_active = False
        #清空外星人列表和子弹列表
        pygame.mouse.set_visible(True)

    aliens.empty()
    bullents.empty()

    #创建一群新的外星人
    create_fleet(ai_settings,screen,ship,aliens)
    ship.center_ship()

    #暂停
    sleep(3)

def check_aliens_bottom(ai_settings,screen,stats,ship,sb,aliens,bullets):
    """检查是否有外星人到达了屏幕底部"""
    screen_rect = screen.get_rect()
    for alien in aliens.sprites():
        if alien.rect.bottom >= screen_rect.bottom:
             #像飞船被撞到一样处理
             ship_hit(ai_settings,stats,screen,ship,sb,aliens,bullets)
             break

def check_high_score(stats,sb):
    """检查是否诞生了新的得分最高"""
    if stats.score > stats.high_score:
        stats.high_score = stats.score
        sb.prep_high_score()

View Code

下面是安装函数 settings

必威电竞 8必威电竞 9

class Settings():
    """A class to store all settings for Alien Invasion."""

    def __init__(self):
        """Initialize the game's settings."""
        # Screen settings
        self.screen_width = 1100
        self.screen_height = 700
        self.bg_color = (230, 230, 230)

        # 飞船设置
        #self.ship_speed_factor = 1.5
        #self.bullet_speed_factor = 3
        self.ship_limit = 3

        # Bullet settings
        self.bullet_speed_factor = 3
        self.bullet_width = 3
        self.bullet_height = 25
        self.bullet_color = 60, 60, 60
        self.bullets_allowed = 2

        #外星人设置
        #self.alien_speed_factor = 1
        self.fleet_drop_speed = 10
        #fleet_direction为1表示向右移动,-1表示向左移动
        self.fleet_direction = 1

        #以什么样的速度加快游戏节奏
        self.fleet_drop_speed = 10

        #加快游戏节奏的速度
        self.speedup_scale = 1.1
        #外星人点数提高
        self.score_scale = 1.5

        self.initialize_dynamic_settings()

    def increase_speed(self):
        """提高速度设置"""
        self.ship_speed_factor *= self.speedup_scale
        self.bullet_speed_factor *= self.speedup_scale
        self.alien_speed_factor *= self.speedup_scale

        self.alien_points  = int(self.alien_points * self.score_scale)
        #print(self.alien_points)

    def initialize_dynamic_settings(self):
        """初始化岁游戏进行二变化的设置"""
        self.ship_speed_factor = 1.5
        self.bullet_speed_factor = 3
        self.alien_speed_factor = 3

        # fleet_direction为1表示向右移动,-1表示向左移动
        self.fleet_direction = 1

        #积分
        self.alien_points = 50

View Code

此是我方飞机的安装函数ship.py

必威电竞 10必威电竞 11

import pygame
from pygame.sprite import Sprite

class Ship(Sprite):
    def __init__(self, ai_settings, screen):
        """Initialize the ship, and set its starting position."""
        super(Ship,self).__init__()

        self.screen = screen
        self.ai_settings = ai_settings

        # Load the ship image, and get its rect.
        self.image = pygame.image.load('images/ship.bmp')
        self.rect = self.image.get_rect()
        self.screen_rect = screen.get_rect()

        # Start each new ship at the bottom center of the screen.
        self.rect.centerx = self.screen_rect.centerx
        self.rect.bottom = self.screen_rect.bottom

        # Store a decimal value for the ship's center.
        self.center = float(self.rect.centerx)

        # Movement flags.
        self.moving_right = False
        self.moving_left = False

    def update(self):
        """Update the ship's position, based on movement flags."""
        # Update the ship's center value, not the rect.
        if self.moving_right and self.rect.right < self.screen_rect.right:
            self.center += self.ai_settings.ship_speed_factor
        if self.moving_left and self.rect.left > 0:
            self.center -= self.ai_settings.ship_speed_factor

        # Update rect object from self.center.
        self.rect.centerx = self.center

    def blitme(self):
        """Draw the ship at its current location."""
        self.screen.blit(self.image, self.rect)

    def center_ship(self):
         """让飞船在屏幕上剧中"""
         self.center = self.screen_rect.centerx

View Code

是是对方飞机的设置函数alien.py

必威电竞 12必威电竞 13

import pygame
from pygame.sprite import Sprite

class Alien(Sprite):
    """表示单个外星人"""

    def __init__(self,ai_settings,screen):
        """初始化外星人并设置其起始位置"""
        super(Alien,self).__init__()
        self.screen = screen
        self.ai_settings = ai_settings

        #加载外星人图像,并设置rect属性
        self.image = pygame.image.load('images/alien.bmp')
        self.rect = self.image.get_rect()

        #每个外星人最初都在屏幕右上角附近
        self.rect.x = self.rect.width
        self.rect.y = self.rect.height

        #存储外星人的准确位置
        self.x = float(self.rect.x)

    def check_edges(self):
        """如果外星人位于屏幕边缘,就返回True"""
        screen_rect = self.screen.get_rect()
        if self.rect.right >=screen_rect.right:
            return True
        elif self.rect.left <=0:
            return True

    def update(self):
        """向左或者向右移动外星人"""
        self.x  += (self.ai_settings.fleet_direction * self.ai_settings.alien_speed_factor)
        self.rect.x = self.x

    def blitme(self):
        """在指定位置绘制外星人"""
        self.screen.blit(self.image,self.rect)

View Code

夫是枪弹设置的函数bullet.py

必威电竞 14必威电竞 15

import pygame
from pygame.sprite import Sprite


class Bullet(Sprite):
    """A class to manage bullets fired from the ship"""

    def __init__(self, ai_settings, screen, ship):
        """Create a bullet object at the ship's current position."""
        super(Bullet, self).__init__()
        self.screen = screen
        # Create a bullet rect at (0, 0) and then set correct position.
        self.rect = pygame.Rect(0, 0, ai_settings.bullet_width,
                                ai_settings.bullet_height)
        self.rect.centerx = ship.rect.centerx
        self.rect.top = ship.rect.top

        # Store the bullet's position as a decimal value.
        self.y = float(self.rect.y)
        self.color = ai_settings.bullet_color
        self.speed_factor = ai_settings.bullet_speed_factor

    def update(self):
        """Move the bullet up the screen."""
        # Update the decimal position of the bullet.
        self.y -= self.speed_factor
        # Update the rect position.
        self.rect.y = self.y

    def draw_bullet(self):
        """Draw the bullet to the screen."""
        pygame.draw.rect(self.screen, self.color, self.rect)

View Code

以此是按钮设置的函数button.py

必威电竞 16必威电竞 17

import pygame.font

class  Button():

    def __init__(self,ai_settings,screen,msg):
        """初始化按钮的属性"""
        self.screen = screen
        self.screen_rect = screen.get_rect()

        #设置按钮的尺寸和其他属性
        self.width,self.height = 200,50
        self.button_color = (0,255,0)
        self.text_color = (255,255,255)
        self.font = pygame.font.SysFont(None,48)

        #创建按钮的rect对象,并使其剧中
        self.rect = pygame.Rect(0,0,self.width,self.height)
        self.rect.center = self.screen_rect.center

        #按钮的标签只需要一次
        self.prep_msg(msg)

    def prep_msg(self,msg):
        """将msg渲染为图像,并使其在按钮上居中"""
        self.msg_image = self.font.render(msg,True,self.text_color,self.button_color)
        self.msg_image_rect = self.msg_image.get_rect()
        self.msg_image_rect.center = self.rect.center


    def draw_button(self):
        #绘制一个用颜色填充的按钮,再绘制文本
        self.screen.fill(self.button_color,self.rect)
        self.screen.blit(self.msg_image,self.msg_image_rect)

View Code

本条是记分牌设置的函数scoreboard.py

必威电竞 18必威电竞 19

import pygame.font
from pygame.sprite import Group

from  ship import Ship

class Scoreboard():
    """显示得分信息的类"""
    def __init__(self,ai_settings,screen,stats):
        """初始化显示得分涉及的属性"""
        self.screen = screen
        self.screen_rect = screen.get_rect()
        self.ai_settings = ai_settings
        self.stats = stats


        #显示得分信息时候使用的字体设置
        self.text_color = (30,30,30)
        self.font = pygame.font.SysFont(None,48)

        #准备初始得分图像
        self.prep_score()
        self.prep_high_score()
        self.prep_level()
        self.prep_ships()

        #准备包含最高分和当前的分的图像
        self.prep_score()
        self.prep_high_score()


    def prep_score(self):
        """将得分转化为一副渲染的图像"""
        rounded_score = int(round(self.stats.score,-1))
        score_str = "{: ,}".format(rounded_score)
        self.score_image = self.font.render(score_str,True,self.text_color,
                                            self.ai_settings.bg_color)

        #将得分放在屏幕右上角
        self.score_rect = self.score_image.get_rect()
        self.score_rect.right = self.screen_rect.right -20
        self.score_rect.top = 20

    def prep_high_score(self):
        """将最高分转换为渲染的图像"""
        high_score = int(round(self.stats.high_score,-1))
        high_score_str = "{: ,}".format(high_score)
        self.high_score_image = self.font.render(high_score_str, True,
                                                 self.text_color,self.ai_settings.bg_color)

        # 将最高得分放在屏幕中央
        self.high_score_rect = self.high_score_image.get_rect()
        self.high_score_rect.centerx = self.screen_rect.centerx
        self.high_score_rect.top = self.score_rect.top

    def show_score(self):
        """在屏幕上显示得分和最高得分"""
        self.screen.blit(self.score_image,self.score_rect)
        self.screen.blit(self.high_score_image,self.high_score_rect)
        self.screen.blit(self.level_image,self.level_rect)
        #绘制飞船
        self.ships.draw(self.screen)

    def prep_level(self):
        """将等级转化为渲染的图像"""
        self.level_image = self.font.render(str(self.stats.level),True,
                                            self.text_color,self.ai_settings.bg_color)

        #将等级放在得分下面
        self.level_rect = self.level_image.get_rect()
        self.level_rect.right = self.score_rect.right
        self.level_rect.top = self.score_rect.bottom +10


    def prep_ships(self):
        """显示还剩下多少搜飞船"""
        self.ships = Group()
        for ship_number in range(self.stats.ships_left):
            ship = Ship(self.ai_settings,self.screen)
            ship.rect.x = 10+ship_number * ship.rect.width
            ship.rect.y = 10
            self.ships.add(ship)

View Code

这是跟踪游戏统计信息之类game_stats.py

必威电竞 20必威电竞 21

class GameStats():
    """跟踪游戏的统计信息"""

    def __init__(self,ai_settings):
        """初始化统计信息"""
        self.ai_settings = ai_settings
        self.reset_stats()

        #游戏刚开始处于0活跃状态
        self.game_active = False

        #在任何情况下都不应重置最高得分
        self.high_score = 0

    def reset_stats(self):
        """初始化在游戏与逆行期间可能变化的统计信息"""
        self.ships_left = self.ai_settings.ship_limit
        self.score = 0
        self.level = 1

View Code

此描绘图片描述

季步:游戏结果展示

图一律:开始界面图:

必威电竞 22

希冀二:游戏受的觊觎

必威电竞 23

 

 

连通下我们重新看一个重新有趣的用户程序,线团火球!在app.c中上加代码如下:

第五步:游戏总结

 
这个游乐做的比较匆忙,还存许多题目,由于小编只是轻车熟路一下pygame,所以并从未举行更充分层次的改良。放到这里,一方面记录自己之修进度,另一方面为欲有想念在游玩者出之对象继续改进。

  
改进建议同样:敌方飞机设置的顶多,游戏体验不是颇好(这个题目,可以对aliens函数进行改动,从而修改敌方飞机的有个数等)

 
改进建议二:每当玩家关闭游戏并再打开下,最高分还见面让重置(这个问题,可以调用在sys.exit()前,将高分写副文件,并于嬉戏记录中初始化最高分并且读取它)

  改进建议三:可以扩大游戏,比如吃外星人也得发飞船,或者外星人加盾等

  改进建议四:可以吃游戏增长音效,让玩家获取重新好之游艺体验

 
改进建议五:可以在卡后面,提高难度不止是敌方飞机快的加快,也可以是更难以打

  改进建议六 :可以安装双人游戏,在平光操作器上面

 
改进建议七:可以安装局域网,让多人口联网操作(但是操作只是为设计者熟悉局域网的代码设置)

(。。。。以后有啊更好之想法,可以补充上来,要是出时光或举行这势头来说,可以还扩展这个代码,这个路是参考《python编程从入门到执行
》的种类)

 

struct POINT {
    int x;
    int y;
};

void main() {
    int win;
    char buf[216*237];
    struct POINT table[18] = {
    {204,129},{195,90},{172,58},{137,38},{98,34},
    {61,46},{31,73},{15,110},{15,148},{31,185},
    {61,212},{98,224},{137,220},{172,200},{195,168},
    {204,129}
    };

    win = api_openwin(buf, 216, 237, -1, "bball");
    api_boxfilwin(win, 8, 29, 207, 228, 255);
    int i = 0, j = 0, dis = 0;
    for (i = 0; i <= 14; i++) {
      for(j = i+1; j <= 15; j++) {
          dis = j - i;
          if (dis >= 8) {
             dis = 15 - dis;
          }
          if (dis != 0) {
             api_linewin(win, table[i].x, table[i].y,
                         table[j].x, table[j].y, 8-dis);
          }
      }
    }

    api_refreshwin(win, 8, 29, 207, 228);
    for (;;) {
        if (api_getkey(1) == 0x1c) {
            break;
        }
    }
    api_closewin(win);

    return;    
}

地方代码运行后效果如下:

必威电竞 24

此地描绘图片描述

绘图出的图是休是那个惊艳,非常灿烂,我们的体系平台还是蛮给力的。

连片下我们只要放大招,开发一个妙趣横生的星球大战游戏。星球大战是如出一辙放缓像素级游戏,它的形态于自身回忆早年,大概是98年,所谓电脑刚传入中华,系统或DOS时,当时上电脑课最欢喜的其实有戏可打。代码比较长,我们分实现,首先在app.c中输入以下代码:

#define win_width 240

void putstr(int win, char *winbuf,char * charset,
 int x, int y, int col, unsigned char *s) {
    int c, x0, i = 0, j;
    char *p, *q, t[2];
    x = x*8+8;
    y = y*16+29;
    x0 = x;
    while (s[i] != 0) {
        i++;
    }

    api_boxfilwin(win, 8, y, win_width - 8 , y+15, 0);

    q = winbuf + y * win_width; 
    t[1] = 0;
    for (;;) {
        c = *s;
        if (c == 0) {
            break;
        }

        if (c != ' ') {
            if ('a' <= c && c <= 'h') {
                p = charset + 16 * (c-'a');
                q += x;
                for (i = 0; i < 16; i++) {

                    if ((p[i] & 0x80) != 0) {q[0] = col;}
                    if ((p[i] & 0x40) != 0) {q[1] = col;}
                    if ((p[i] & 0x20) != 0) {q[2] = col;}
                    if ((p[i] & 0x10) != 0) {q[3] = col;}
                    if ((p[i] & 0x08) != 0) {q[4] = col;}
                    if ((p[i] & 0x04) != 0) {q[5] = col;}
                    if ((p[i] & 0x02) != 0) {q[6] = col;}
                    if ((p[i] & 0x01) != 0) {q[7] = col;}

                    q += win_width; 
                }
                q -= win_width * 16 + x;
            } else if((c>='i' && c <= 'z') || (c>='A' && c <= 'Z')){
                t[0] = *s;
                api_putstrwin(win, x, y, col,1,t);
            }
        }

        s++;
        x += 8;
    }

    api_refreshwin(win,  8, y, win_width - 8, y+15);
}



void main() {
    int win, i, j, ix, iy, fx;
    char winbuf[win_width * 237], invstr[32*6], s[12];
    char* p = winbuf;

    char invstr0[36] = {' ' , 'a','b','c','d',' ' ,'a','b','c','d', ' ',
                         'a','b','c','d',' ',  'a','b','c','d',' ',
                           'a','b','c','d', ' ',
                         0};

    char charset[18 * 8] = {
    0x00, 0x00, 0x00, 0x43, 0x5f, 0x5f, 0x5f, 0x7f,
    0x1f, 0x1f, 0x1f, 0x1f, 0x00, 0x20, 0x3f, 0x00,

    0x00, 0x0f, 0x7f, 0xff, 0xcf, 0xcf, 0xcf, 0xff,
    0xff, 0xe0, 0xff, 0xff, 0xc0, 0xc0, 0xc0, 0x00,

    0x00, 0xf0, 0xfe, 0xff, 0xf3, 0xf3, 0xf3, 0xff,
    0xff, 0x07, 0xff, 0xff, 0x03, 0x03, 0x03, 0x00,

    0x00, 0x00, 0x00, 0xc2, 0xfa, 0xfa, 0xfa, 0xfe,
    0xf8, 0xf8, 0xf8, 0xf8, 0x00, 0x04, 0xfc, 0x00,

    0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
    0x01, 0x43, 0x47, 0x4f, 0x5f, 0x7f, 0x7f, 0x00,

    0x18, 0x7e, 0xff, 0xc3, 0xc3, 0xc3, 0xc3, 0xff,
    0xff, 0xff, 0xe7, 0xe7, 0xe7, 0xe7, 0xff, 0x00,

    0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
    0x80, 0xc2, 0xe2, 0xf2, 0xfa, 0xfe, 0xfe, 0x00,

    0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
    0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00
    };

    win = api_openwin(winbuf, win_width, 237, -1, "invader");
    api_boxfilwin(win, 8, 29, win_width - 6, 228, 0);
    //putstr(win, winbuf, 22, 0, 7, "HIGH:00000000");

restart:
    fx = 18;
    char fly[8] = {'e', 'f', 'g', 0};
    putstr(win, winbuf, charset, 18, 11, 6, fly);

nextgroup:
    ix =  7;
    iy = 1;
    int invline = 6;
    for (i = 0; i < 3; i++) {
        for (j = 0; j < 20; j++) {
            invstr[i * 32 + j] = invstr0[j];
        }
        putstr(win, winbuf,charset, ix, iy + i, 2, invstr + i * 32);
    }


    api_refreshwin(win, 8, 29, 207, 228);

    for(;;) {
        if (api_getkey(1) == 0x1c) {
            break;
        }
    }

    api_closewin(win);

    return;
}

putstr函数有些许个职能,当输入字符在’a’到’h’之间经常,它根据点阵表charset,通过设置有像素点的颜料来绘制图像。其中参数x,y是图像起始坐标,最后一个参数s用来控制图像绘制的点子,例如当最后的s内容为”abcd”时,该函数从charset表中取出前四行数据,其中各一个数值都于告知代码在绘制哪一个像素点,它的绘图原理及早前咱们讲课的怎么样绘制字符是如出一辙的。我们事先看看上面代码运行起来后的动静:

必威电竞 25

这边描绘图片描述

代码绘制了三脱外星人和平等绑架战斗机,在main函数中,代码:

restart:
    fx = 18;
    char fly[8] = {'e', 'f', 'g', 0};
    putstr(win, winbuf, charset, 18, 11, 6, fly);

绘制的便是图底部的战斗机,而代码有:

nextgroup:
    ix =  7;
    iy = 1;
    int invline = 6;
    for (i = 0; i < 3; i++) {
        for (j = 0; j < 20; j++) {
            invstr[i * 32 + j] = invstr0[j];
        }
        putstr(win, winbuf,charset, ix, iy + i, 2, invstr + i * 32);
    }

虽是绘制了美术上之老三解除外星人。

就我们如果惦记方给图像动起来,这就是需动用到我们前做了之定时器。首先,我们先行补充加代码,让飞机因我们按键输入以便实现左右移动,因此我们补充加日下代码:

void putstr(int win, char *winbuf,char * charset,
 int x, int y, int col, unsigned char *s) {
 ....
 }

 void waitting(int i, int timer, char* keyflag) {
    int j;
    if (i > 0) {
        api_settimer(timer, i);
        i = 128;
    } else {
        i = 0x1c;
    }

    for(;;) {
        j = api_getkey(1);
        if (i == j) {
            break;
        }

        if (j == 0x24) {
          //key j
            keyflag[0] = 1;
        }
        if (j == 0x25) {
            //key k
            keyflag[1] = 1;
        }
        if (j == 0x39) {
            //key space
            keyflag[2] = 1;
        }
    }

    return;
}

void main() {
    char keyflag[6];
    ....
    nextgroup:
    ....
    keyflag[0] = 0;
    keyflag[1] = 0;
    keyflag[2] = 0;

    for(;;) {
        waitting(4, timer, keyflag);
        if (keyflag[0] != 0 && fx > 1) {
           //fighter fly to left
           fx--;
           fly[0] = 'e', fly[1] = 'f', fly[2] = 'g', fly[3] = ' ';
           fly[4] = 0;
           putstr(win, winbuf, charset, fx, 11, 6, fly); 
           keyflag[0] = 0;
        }
        if (keyflag[1] != 0 && fx < 24) {
           fx++;
           fly[0] = ' ', fly[1] = 'e', fly[2] = 'f', fly[3] = 'g';
           fly[4] = 0;
           putstr(win, winbuf, charset, fx, 11, 6, fly);
           keyflag[1] = 0;
        }
    }
}

waitting
函数的用意是等待定时器放回结果,同时监控键盘按键,如果用户在键盘上点击按键’j’,那么她经过调用api_getkey就能够得对许扫描码,也不怕是0x24,
如果用户点击按键’k’,那么相应的扫描码为0x25,在main函数里,我们添加一个for循环,在中间我们调用waitting函数获取用户按键信息,当用户仍下’j’后,我们管飞机于左移动一个单位,然后刷新窗口,如果用户点击的是k,那么我们将飞机为右侧走一个单位,然后刷新窗口,上面代码完成后,编译加载到虚拟机,启动程序后,尝试以下仍键’j’,我们得以发现飞机一直为左移动,知道到窗口左边界为止,效果如下:

必威电竞 26

此描绘图片描述

机能活动后,我们需要外星人吗飘飘起来,因此我们添加如下代码:

void main () {
....
    for(;;) {
        waitting(4, timer, keyflag);
        ....
                //move aliens
        if (movewait != 0) {
            movewait--;
        } else {
            movewait = movewait0;
            if (ix + idir > 12 || ix + idir < 1) {
                if (iy + invline == 13) {
                   //game over
                   break;
                }
                idir = -idir;
                putstr(win, winbuf, charset,ix + 1, iy, 0, "  ");
                iy++;
            } else {
                ix += idir;
            }
            for (i = 0; i < invline; i++) {
                putstr(win, winbuf,charset, ix, iy + i, 2, invstr + i * 32);
            }
        } 
    }   
}

地方代码先把外星人向右侧走,直到边缘时,iy++,这即让外星人向下移动,与此同时idir
= -idir;
使得外星人开始倒转往活动,一直顶左侧边缘,这种活动一直当开展,直到外星人的y坐标做够好时,游戏结束。

必威电竞 27

此间描绘图片描述

自从上面我们好看看,飞机活动至左手时,外星人移动及右。接着我们设兑现用户仍下空格键时,飞机能发出炮弹,并且判断一旦炮弹中外星人后,外星人会见给消灭掉,这个效应的落实重大靠下面代码:

for(;;) {
       if (laserwait != 0) {
            laserwait--;
            keyflag[2] = 0;
        }
        ....
       //draw laser bullet
        if (ly > 0) {
            if (ly < 8) {
                if (ix < lx && lx < ix + 25 && iy <= ly && ly < iy + invline) {
                    putstr(win, winbuf, charset, ix, ly, 2, invstr + (ly - iy) * 32);
                }//if (ix < lx ...)
                else {
                    putstr(win, winbuf, charset, lx, ly, 0, "  ");
               }
            }//if(ly < 13)
            ly--;
            if (ly > 0) {
                char c[2] = {'h', 0};
                putstr(win, winbuf,charset, lx, ly, 3, c);
            } // if(ly > 0)

            if (ix < lx && lx < ix + 25 && iy <= ly && ly < iy + invline) {
               p = invstr + (ly - iy) * 32 + (lx - ix);
               if (*p != ' ' ) {
                   //hit
                   for(p--; *p != ' '; p--) {}
                   for (i = 1; i < 5; i++) {
                       p[i] = ' ';
                   }
                  putstr(win, winbuf, charset, ix, ly, 2, invstr+(ly-iy)*32);
                  for(; invline > 0; invline--) {
                      for(p = invstr + (invline-1)*32; *p != 0; p++) {
                          if (*p != ' ') {
                              goto alive;
                          }
                      }
                  } 
            gameover:
                  //hit all 
                  movewait0 -= movewait0 / 3;
                  char gameover[12] = {'G','A','M','E',' ','O','V','E','R'};
                  putstr(win, winbuf, charset, 15, 6, 1, gameover);
                  waitting(10, timer, keyflag);

                  goto nextgroup;
            alive:
                  ly = 0;
               }
            } //if(ix < lx...)

        }//if (ly > 0)
    }
}

方代码使得,当用户点击空格键时,程序即使准备于飞机处于放出导弹。代码有:

 if (ly > 0) {
                char c[2] = {'h', 0};
                putstr(win, winbuf,charset, lx, ly, 3, c);
            } // if(ly > 0)

它的意向是,如果用户点击了空格,同时外星人还尚未入侵到飞机所当的势力范围,那么我们不怕绘制一个打最底层向上发射的炮弹,接下去的多重代码是,当炮弹发射后,判断炮弹是否中外星人,如果从至了,被击中的外星人要由屏幕上磨不见,这有逻辑实现的情如下:

必威电竞 28

此描绘图片描述

由上图可以视,黄色的竖线块就是飞机发射出之导弹,中间就排外星人给击毙了,所以在屏幕及从未有过显示出来。如果外星人下降到飞机所在高度,那么闹游戏了,如果外星人全部叫击毙,那么战机成功保地球,游戏吗结:

必威电竞 29

这里描绘图片描述

娱乐结束晚,”GAME OVER”会打印及界面上,然后一切游戏还来平等遍。

是星球大战游戏是系基本开发暨者,我们开过的最为复杂的客户程序,它调用了几乎所有api,例如窗口绘制,字符串输出,时钟,键盘监听等等,这个复杂程序的成运行,在肯定水平达到标明,我们的系统基本具备一定水准之纷繁和鲁棒性,虽然其不行及规范操作系统同日而语,但不怕她还简单,再复杂,它为本着得打一个“操作系统”的名称。

再次详尽的讲授和代码调试演示过程,请参考视频
Linux kernel Hacker,
从零构建好的基石

再多技术信息,包括操作系统,编译器,面试算法,机器上,人工智能,请看我之民众号:

必威电竞 30

此处描绘图片描述

相关文章

admin

网站地图xml地图