Mini projects #8–RiceRocks

课程全名:An Introduction to Interactive Programming in Python,来自 Rice University

授课教授:Joe Warren, Scott Rixner, John Greiner, Stephen Wong

工具:http://www.codeskulptor.org/, simplegui 模块

最后一个project,继续完善上一周的工程,做完就是一个既简单又棒棒的打陨石(飞机)游戏。

第八周:

关于Python的知识,set类型的用法

定义:set和C++中的STL中的set类似,用来维护一组不重复的无序元素。

# 定义一个空的set
set_empty = set() # or set([])
print set_empty
# set([])

# 定义set
set_a = set([1, 2, 3])
set_b = set((1, 2, 3))
set_c = set({1:1, 2:1, 3:1})
set_d = set("abcd")
set_e = set(["a", "b", "cd"])
print set_a, set_b, set_c
print set_d, set_e
# set([1, 2, 3]) set([1, 2, 3]) set([1, 2, 3])
# set([‘a‘, ‘b‘, ‘c‘, ‘d‘]) set([‘a‘, ‘b‘, ‘cd‘])

# set的交、并、差运算、对称差集
# 这些操作返回一个新的集合,set_a,set_b不发生改变
set_a = set([1, 2, 3])
set_b = set([2, 3, 4])
print set_a.intersection(set_b)
# set([2, 3])
print set_a.union(set_b)
# set([1, 2, 3, 4])
print set_a.difference(set_b)
# set([1])
print set_a.symmetric_difference(set_b)
# set([1, 4])

# 这些对应操作没有返回值,并且直接改变set_a,set_b不变化
set_a.intersection_update(set_b)
set_a.update(set_b) # 添加多个元素,就是union含义
set_a.difference_update(set_b)
set_a.symmetric_difference_update(set_b)

# set 其他的操作符
s = set([1, 2, 3, 4])
s.add(5) # 添加单个元素
s.add(4) # 重复元素没有效果
s.remove(4) # 移除集合中的元素,如果元素不存在会报错
s.discard(8) # 也是移除集合中的元素,但是对于不存在元素不影响
s.pop() # 弹出集合中的任意一个元素,如果集合为空执行该操作报错

set([2, 9, 7, 1].issubset(set([1, 7])) # 判断是否是子集,返回True或者False
set([2, 9, 7, 1]).issuperset(set([1, 7])) # 判断是否是父集,返回True或者False

set因为是无序集合,所以不支持index索引和slice([ ])切片的操作,可以用element in set来判断集合是否存在该元素。或者for 循环用iterable遍历。

set和list是可变类型,下面的a和b都是指向同一个空间位置。

a = set([1, 2, 3])
b = a
print a
# set([1, 2, 3])
b.add(4)
print a
# set([1, 2, 3, 4])

Python知识介绍完,上游戏图

回顾上周,完成了一个飞船,一个陨石,一个子弹。

基本的绘制、更新以及大部分的方法都已经实现,这一周主要是实现多个陨石以及子弹的连续发射,还有加上飞船三者之间碰撞的关系处理。

对于游戏来说,掌握关键的一帧,核心就在draw的绘制中:

· 更新时间,绘制背景元素

· 绘制和更新my_ship

· 如果游戏开始

· 绘制更新rock_group

· 绘制更新missile_group

· 绘制更新explosion_group

· 如果 rock_group和my_ship碰撞,lives –= 1

· 如果 lives<=0,init_game()

· score 加上发生rock_group与missile_group碰撞的数量(biu~~~~)

· 游戏没开始就换个splah提示

· 绘制lives text

· 绘制score text

# draw handler
def draw(canvas):
    global time, lives, rock_group, missile_group, my_ship, score, started

    # animiate background
    time += 1
    wtime = (time / 4) % WIDTH
    center = debris_info.get_center()
    size = debris_info.get_size()
    canvas.draw_image(nebula_image, nebula_info.get_center(), nebula_info.get_size(), [WIDTH / 2, HEIGHT / 2], [WIDTH, HEIGHT])
    canvas.draw_image(debris_image, center, size, (wtime - WIDTH / 2, HEIGHT / 2), (WIDTH, HEIGHT))
    canvas.draw_image(debris_image, center, size, (wtime + WIDTH / 2, HEIGHT / 2), (WIDTH, HEIGHT))    

    # draw and update ship
    my_ship.draw(canvas)
    my_ship.update()

    if started:

        # draw and update rock_group
        process_sprite_group(rock_group, canvas)

        # draw and update missile_group
        process_sprite_group(missile_group, canvas)

        # draw and update explosioin_group
        process_sprite_group(explosion_group, canvas)

        # ship - rock_group collide and update the lives
        if group_collide(rock_group, my_ship):
            lives -= 1
        # game over
        if lives <= 0:
            init_game()
            message_label.set_text(‘Click to start!‘)
        # update score
        score += group_group_collide(rock_group, missile_group) * 10

    else:
        canvas.draw_image(splash_image, splash_info.get_center(), splash_info.get_size(), (WIDTH / 2, HEIGHT / 2), splash_info.get_size()) 

    # draw lives
    canvas.draw_text("Lives", [WIDTH / 12, HEIGHT / 12], 30, "White")
    canvas.draw_text(str(lives), [WIDTH / 12, HEIGHT / 12 + 40], 30, "White")

    # draw score
    canvas.draw_text("Score", [10 * WIDTH / 12, HEIGHT/12], 30, "White")
    canvas.draw_text(str(score), [10 * WIDTH /12, HEIGHT/12 + 40], 30, "White")

my_ship的绘制更新上周已经完成,上周主要处理一个陨石和子弹的情形,这周完成都过,奥秘就在process_sprite_group()中。

def process_sprite_group(sprite_group, canvas):
    remove_set = set([])
    for sprite in sprite_group:
        sprite.draw(canvas)
        if sprite.update():
            remove_set.add(sprite)
    sprite_group.difference_update(remove_set)

process_sprite_group完成对group中每一个对象的绘制和更新,sprite.update()的if判断主要是针对子弹,子弹发生是存在距离,这个距离通过age时间来衡量,当sprite.lifespan超过了age,那么update就返回True,我们就要把这些过了保质期的子弹从他的group中移走,而默认rock陨石的lifespan保质期是inf,永不过期,除非被飞机打掉了。这样通过process_sprite_group就可以维护rock_group,missile_group,explosion_group.

那么接下来重要的问题来了?挖掘机….处理元素之间的碰撞关系。这里碰撞主要存在两种,飞机与陨石之间碰撞,陨石和子弹之间碰撞。

def group_collide(group, other_object):
    is_collide = False
    remove_set = set([])
    for obj in group:
        if obj.collide(other_object):
            is_collide = True
            remove_set.add(obj)
            # create new explosion
            pos = [other_object.pos[0], other_object.pos[1]]
            new_explosion = Sprite(pos, [0, 0], other_object.angle, 0, explosion_image, explosion_info, explosion_sound)
            explosion_group.add(new_explosion)

    group.difference_update(remove_set)
    return is_collide

def group_group_collide(group, other_group):
    num_collide = 0
    for obj in list(group):
        if group_collide(other_group, obj):
            group.discard(obj)
            num_collide += 1
    return num_collide

通过上面两个Help Function,第一个可以用来检测rock_group和my_ship,需要实现一个sprite的collide方法,用距离和半径和的关系判断是否碰撞,然后再group_collide函数中只要遍历rock_group,调用collide方法判断是否和my_ship相撞。相撞的元素从group中移走,为了实现explosion的效果,在这里向explosion_group添加以other_project坐标属性的新元素。

第二个,主要用来监测rock_group和missile_group的碰撞关系,遍历rock_group然后在调用group_collide方法,判断单个元素和group之间碰撞(复用大法好)。

碰撞检测后,记得更新score 和 lives的值。

游戏的核心也就差不多了。剩下的就没什么了。started变量控制一下游戏开始状态,基本的Tile的图像绘制,加个偏移就好。再有就是一些加速的参数需要自己手工调整,关乎你游戏的可玩性。忘记一点,随机生成rock的时候,加一个判断当坐标离自己飞船在一定范围之外,才能生成,不然莫宁奇妙的躺枪。

一个陨石10分,无聊的加了个button,500分换一条命。

下面就贴完整代码:

# program template for Spaceship
import simplegui
import math
import random

# globals for user interface
WIDTH = 800
HEIGHT = 600
score = 0
lives = 3
time = 0.5

class ImageInfo:
    def __init__(self, center, size, radius = 0, lifespan = None, animated = False):
        self.center = center
        self.size = size
        self.radius = radius
        if lifespan:
            self.lifespan = lifespan
        else:
            self.lifespan = float(‘inf‘)
        self.animated = animated

    def get_center(self):
        return self.center

    def get_size(self):
        return self.size

    def get_radius(self):
        return self.radius

    def get_lifespan(self):
        return self.lifespan

    def get_animated(self):
        return self.animated

# art assets created by Kim Lathrop, may be freely re-used in non-commercial projects, please credit Kim

# debris images - debris1_brown.png, debris2_brown.png, debris3_brown.png, debris4_brown.png
#                 debris1_blue.png, debris2_blue.png, debris3_blue.png, debris4_blue.png, debris_blend.png
debris_info = ImageInfo([320, 240], [640, 480])
debris_image = simplegui.load_image("http://commondatastorage.googleapis.com/codeskulptor-assets/lathrop/debris2_blue.png")

# nebula images - nebula_brown.png, nebula_blue.png
nebula_info = ImageInfo([400, 300], [800, 600])
nebula_image = simplegui.load_image("http://commondatastorage.googleapis.com/codeskulptor-assets/lathrop/nebula_blue.f2014.png")

# splash image
splash_info = ImageInfo([200, 150], [400, 300])
splash_image = simplegui.load_image("http://commondatastorage.googleapis.com/codeskulptor-assets/lathrop/splash.png")

# ship image
ship_info = ImageInfo([45, 45], [90, 90], 35)
ship_image = simplegui.load_image("http://commondatastorage.googleapis.com/codeskulptor-assets/lathrop/double_ship.png")

# missile image - shot1.png, shot2.png, shot3.png
missile_info = ImageInfo([5,5], [10, 10], 3, 50)
missile_image = simplegui.load_image("http://commondatastorage.googleapis.com/codeskulptor-assets/lathrop/shot2.png")

# asteroid images - asteroid_blue.png, asteroid_brown.png, asteroid_blend.png
asteroid_info = ImageInfo([45, 45], [90, 90], 40)
asteroid_image = simplegui.load_image("http://commondatastorage.googleapis.com/codeskulptor-assets/lathrop/asteroid_blue.png")

# animated explosion - explosion_orange.png, explosion_blue.png, explosion_blue2.png, explosion_alpha.png
explosion_info = ImageInfo([64, 64], [128, 128], 17, 24, True)
explosion_image = simplegui.load_image("http://commondatastorage.googleapis.com/codeskulptor-assets/lathrop/explosion_alpha.png")

# sound assets purchased from sounddogs.com, please do not redistribute
soundtrack = simplegui.load_sound("http://commondatastorage.googleapis.com/codeskulptor-assets/sounddogs/soundtrack.mp3")
missile_sound = simplegui.load_sound("http://commondatastorage.googleapis.com/codeskulptor-assets/sounddogs/missile.mp3")
missile_sound.set_volume(.5)
ship_thrust_sound = simplegui.load_sound("http://commondatastorage.googleapis.com/codeskulptor-assets/sounddogs/thrust.mp3")
explosion_sound = simplegui.load_sound("http://commondatastorage.googleapis.com/codeskulptor-assets/sounddogs/explosion.mp3")

# helper functions to handle transformations
def angle_to_vector(ang):
    return [math.cos(ang), math.sin(ang)]

def dist(p,q):
    return math.sqrt((p[0] - q[0]) ** 2+(p[1] - q[1]) ** 2)

# Ship class
class Ship:
    def __init__(self, pos, vel, angle, image, info):
        self.pos = [pos[0],pos[1]]
        self.vel = [vel[0],vel[1]]
        self.thrust = False
        self.angle = angle
        self.angle_vel = 0
        self.image = image
        self.image_center = info.get_center()
        self.image_size = info.get_size()
        self.radius = info.get_radius()

    def draw(self,canvas):
        if self.thrust:
            center = (self.image_center[0]+self.image_size[0], self.image_center[1])
            canvas.draw_image(self.image, center, self.image_size, self.pos, self.image_size, self.angle)
        else:
            canvas.draw_image(self.image, self.image_center, self.image_size, self.pos, self.image_size, self.angle)

    def update(self):
        self.angle += self.angle_vel
        self.pos[0] = (self.pos[0] + self.vel[0]) % WIDTH
        self.pos[1] = (self.pos[1] + self.vel[1]) % HEIGHT
        c = 0.05
        self.vel[0] *= (1 - c)
        self.vel[1] *= (1 - c)
        forward = angle_to_vector(self.angle)
        if self.thrust:
            self.vel[0] += forward[0] * 0.8
            self.vel[1] += forward[1] * 0.8

    def change_angle_vel(self, ori, key_state):
        if ((ori == "right" and key_state == "keyup") or
            (ori == "left" and key_state == "keydown")):
            self.angle_vel -= 0.1
        elif ((ori == "right" and key_state == "keydown") or
            (ori == "left" and key_state == "keyup")):
            self.angle_vel += 0.1

    def set_thruster(self, thruster_state):
        self.thrust = thruster_state
        if self.thrust:
            ship_thrust_sound.rewind()
            ship_thrust_sound.play()
        else:
            ship_thrust_sound.rewind()

    def shoot(self):
        global missile_group
        offset = self.image_size[0] / 2.0
        forward = angle_to_vector(self.angle)
        pos = [self.pos[0] + offset * forward[0], self.pos[1] + offset * forward[1]]
        vel = [self.vel[0] + 6 * forward[0], self.vel[1] + 6 * forward[1]]
        ang = 0
        ang_vel = 0
        missile_group.add(Sprite(pos, vel, ang, ang_vel, missile_image, missile_info, missile_sound))

    def get_position(self):
        return self.pos

    def get_radius(self):
        return self.radius

# Sprite class
class Sprite:
    def __init__(self, pos, vel, ang, ang_vel, image, info, sound = None):
        self.pos = [pos[0],pos[1]]
        self.vel = [vel[0],vel[1]]
        self.angle = ang
        self.angle_vel = ang_vel
        self.image = image
        self.image_center = info.get_center()
        self.image_size = info.get_size()
        self.radius = info.get_radius()
        self.lifespan = info.get_lifespan()
        self.animated = info.get_animated()
        self.age = 0
        if sound:
            sound.rewind()
            sound.play()

    def draw(self, canvas):
        if self.animated:
            center = (self.image_center[0] + self.age * self.image_size[0], self.image_center[1])
            canvas.draw_image(self.image, center, self.image_size, self.pos, self.image_size, self.angle)
        else:
            canvas.draw_image(self.image, self.image_center, self.image_size, self.pos, self.image_size, self.angle)

    def update(self):
        if started:
            self.angle += self.angle_vel
            self.pos[0] = (self.pos[0] + self.vel[0]) % WIDTH
            self.pos[1] = (self.pos[1] + self.vel[1]) % HEIGHT

            self.age += 1
            if self.age >= self.lifespan:
                return True
            else:
                return False

    def get_position(self):
        return self.pos

    def get_radius(self):
        return self.radius

    def collide(self, other_object):
        dis = self.get_radius() + other_object.get_radius()
        if dis > dist(self.get_position(), other_object.get_position()):
            return True
        else:
            return False

# Help Function to deal collision
def group_collide(group, other_object):
    is_collide = False
    remove_set = set([])
    for obj in group:
        if obj.collide(other_object):
            is_collide = True
            remove_set.add(obj)
            # create new explosion
            pos = [other_object.pos[0], other_object.pos[1]]
            new_explosion = Sprite(pos, [0, 0], other_object.angle, 0, explosion_image, explosion_info, explosion_sound)
            explosion_group.add(new_explosion)

    group.difference_update(remove_set)
    return is_collide

def group_group_collide(group, other_group):
    num_collide = 0
    for obj in list(group):
        if group_collide(other_group, obj):
            group.discard(obj)
            num_collide += 1
    return num_collide

def process_sprite_group(sprite_group, canvas):
    remove_set = set([])
    for sprite in sprite_group:
        sprite.draw(canvas)
        if sprite.update():
            remove_set.add(sprite)
    sprite_group.difference_update(remove_set)

# draw handler
def draw(canvas):
    global time, lives, rock_group, missile_group, my_ship, score, started

    # animiate background
    time += 1
    wtime = (time / 4) % WIDTH
    center = debris_info.get_center()
    size = debris_info.get_size()
    canvas.draw_image(nebula_image, nebula_info.get_center(), nebula_info.get_size(), [WIDTH / 2, HEIGHT / 2], [WIDTH, HEIGHT])
    canvas.draw_image(debris_image, center, size, (wtime - WIDTH / 2, HEIGHT / 2), (WIDTH, HEIGHT))
    canvas.draw_image(debris_image, center, size, (wtime + WIDTH / 2, HEIGHT / 2), (WIDTH, HEIGHT))    

    # draw and update ship
    my_ship.draw(canvas)
    my_ship.update()

    if started:

        # draw and update rock_group
        process_sprite_group(rock_group, canvas)

        # draw and update missile_group
        process_sprite_group(missile_group, canvas)

        # draw and update explosioin_group
        process_sprite_group(explosion_group, canvas)

        # ship - rock_group collide and update the lives
        if group_collide(rock_group, my_ship):
            lives -= 1
        # game over
        if lives <= 0:
            init_game()
            message_label.set_text(‘Click to start!‘)
        # update score
        score += group_group_collide(rock_group, missile_group) * 10

    else:
        canvas.draw_image(splash_image, splash_info.get_center(), splash_info.get_size(), (WIDTH / 2, HEIGHT / 2), splash_info.get_size()) 

    # draw lives
    canvas.draw_text("Lives", [WIDTH / 12, HEIGHT / 12], 30, "White")
    canvas.draw_text(str(lives), [WIDTH / 12, HEIGHT / 12 + 40], 30, "White")

    # draw score
    canvas.draw_text("Score", [10 * WIDTH / 12, HEIGHT/12], 30, "White")
    canvas.draw_text(str(score), [10 * WIDTH /12, HEIGHT/12 + 40], 30, "White")

# timer handler that spawns a rock
def rock_spawner():
    global rock_group
    if started and len(rock_group) < 12:
        pos = [random.randint(0, WIDTH-1), random.randint(0, HEIGHT-1)]
        # dist great than 20 can spawn a new rock
        if dist(pos, my_ship.get_position()) > 150:
            vel = [random.randrange(1, 3, 1)*random.choice([1, -1]), random.randrange(1, 3, 1)*random.choice([1, -1])]
            ang = 0
            ang_vel = random.randrange(5, 10, 1) / 100.0 * random.choice([1, -1])
            new_rock = Sprite(pos, vel, ang, ang_vel, asteroid_image, asteroid_info)
            rock_group.add(new_rock)

# key_up handler
def key_up(key):
    if started:
        if simplegui.KEY_MAP[‘left‘] == key:
            my_ship.change_angle_vel("left", "keyup")
        elif simplegui.KEY_MAP[‘right‘] == key:
            my_ship.change_angle_vel("right", "keyup")
        elif simplegui.KEY_MAP[‘up‘] == key:
            my_ship.set_thruster(False)

# key_down handler
def key_down(key):
    if started:
        if simplegui.KEY_MAP[‘left‘] == key:
            my_ship.change_angle_vel("left", "keydown")
        elif simplegui.KEY_MAP[‘right‘] == key:
            my_ship.change_angle_vel("right", "keydown")
        elif simplegui.KEY_MAP[‘up‘] == key:
            my_ship.set_thruster(True)
        elif simplegui.KEY_MAP[‘space‘] == key:
            my_ship.shoot()

# mouse_click handler
def mouse_click(position):
    global started
    if position[0] < WIDTH and position[1] < HEIGHT and not started :
        started = True
        soundtrack.rewind()
        soundtrack.play()
        message_label.set_text(‘Welcome, enjoy!‘)

# puchase button handler:
def purchase_button():
    global score, lives, message_label
    if started:
        if score >= 500:
            score -= 500
            lives += 1
            message_label.set_text("Purchase successfully.")
        else:
            message_label.set_text("Scores are not enough.")
    else:
        message_label.set_text("Game hasn‘t started yet.")

# exit game button
def exit_button():
    soundtrack.rewind()
    ship_thrust_sound.rewind()
    missile_sound.rewind()
    explosion_sound.rewind()
    frame.stop()

# init the game state
def init_game():
    global my_ship, rock_group, missile_group, explosion_group, started, score, lives
    # initialize ship and two sprites
    my_ship = Ship([WIDTH / 2, HEIGHT / 3], [0, 0], 1.5*math.pi, ship_image, ship_info)
    rock_group = set([])
    missile_group = set([])
    explosion_group = set([])
    score, lives = 0, 3
    started = False
    soundtrack.rewind()
    ship_thrust_sound.rewind()
    missile_sound.rewind()
    explosion_sound.rewind()

# initialize frame
frame = simplegui.create_frame("Asteroids", WIDTH, HEIGHT)

# init the game
init_game()

# register handlers
frame.set_draw_handler(draw)
frame.set_keydown_handler(key_down)
frame.set_keyup_handler(key_up)
frame.set_mouseclick_handler(mouse_click)
frame.add_button(‘500 Scores for a life‘, purchase_button, 200)
frame.add_button(‘Quit‘, exit_button, 200)
message_label = frame.add_label(‘Click to start!‘)
author_label = frame.add_label(‘Tiny656‘)
contact_label = frame.add_label(‘[email protected]‘)
timer = simplegui.create_timer(1000.0, rock_spawner)

# get things rolling
timer.start()
frame.start()

坐等最后的Peer Evaluation,这么课应该就结束了,感谢Rice大学这些兢兢业业对于教学富有激情和创意的老师,能让我有幸聆听到这么有意思的课程,收获满满,感谢Coursera这么棒棒的平台,拉近了每个人与知识的距离,对于充满好奇心的我,一比无价的财富。现在的环境是,永远不缺知识以及还有这么多优秀的知识分享者,缺少一颗渴望学习的心,不管做什么,耐心和毅力总能感觉到自己不断成长的步伐,学习的道路上,永远不应该放下脚步,引用Jobs的话,stay hungry, stay foolish, 求知若饥求知若愚。

接下来开始认真跟Princeton的算法II,妈蛋的,第二周都放出来了,第一周的视频还一点没看,得抓紧。还有老板的活要干,还有英语要复习,真是分神乏力。咬咬牙,坚持下来。12月开始刷题复习,明年找工作。

时间: 2024-10-27 03:52:08

Mini projects #8–RiceRocks的相关文章

Mini projects #7 ---- Spaceship

课程全名:An Introduction to Interactive Programming in Python,来自 Rice University 授课教授:Joe Warren, Scott Rixner, John Greiner, Stephen Wong 工具:http://www.codeskulptor.org/, simplegui 模块 最后两周就要结束了~~~ 第七周: 先上图,这周完成Spaceship游戏的一部分. 在这图里面有什么?飞船,陨石,子弹,背景图-. 用O

Mini projects ---- Stopwatch: The Game

课程全名:An Introduction to Interactive Programming in Python,来自 Rice University 授课教授:Joe Warren, Scott Rixner, John Greiner, Stephen Wong 工具:http://www.codeskulptor.org/, simplegui 模块 这是第三次作业,前面两次主要是熟悉Python动手做起来都很简单,就不记录了. 作业需要完成一个关于手表的游戏,估计很多人也都玩过.初中和

Mini projects ---- Pong

课程全名:An Introduction to Interactive Programming in Python,来自 Rice University 授课教授:Joe Warren, Scott Rixner, John Greiner, Stephen Wong 工具:http://www.codeskulptor.org/, simplegui 模块 第四次作业,完成一个弹球的游戏,游戏的界面如下,规则也很简单,球不断在两边的paddle之间撞击后速度会不断加快,直到有一名玩家无法将球回

.NET Open Source Developer Projects

There are many .NET open source developer projects. This list is intended to provide links to projects on CodePlex or it GitHub.  The recent .NET Core Open Source is on GitHub .NET Implementations .NET Core - Core .NET Framework Mono Project - Cross-

A Complete List of .NET Open Source Developer Projects

http://scottge.net/2015/07/08/a-complete-list-of-net-open-source-developer-projects/?utm_source=tuicool NET Implementations .NET Core – Core .NET Framework C# Native – Compiles C# to native. Cosmos – C# Open Source Managed Operating System, an operat

Building Xcode iOS projects and creating *.ipa file from the command line

For our development process of iOS applications, we are using Jenkins set up on the Mac Mini Server, acting as a Continuous Integration (CI) server. It’s fairly easy to configure Jenkins for Xcode projects using Xcode Plugin - however, from time to t

如何在Eclipse中使用依赖项目(Required projects)代替jar

最近想看下spring的源码,下了源码后,搭建个简单的例子hellospring的web项目,采用工程依赖使用源码中的类.搭建好后启动tomcat报java.lang.ClassNotFoundException: org.springframework.web.servlet.DispatcherServlet错误.参考了下面文章. 在Eclipse中使用依赖项目(Required projects)替换jar的好处就是可以随时更改依赖项目中的代码,而在主项目中引用到最新的编译类.这种方式在D

手动制作mini linux详细步骤—之一

8.2.1.mini linux内核编译 实验目的: 对Linux内核以非模块化手动编译,并借助busybox安装根文件系统,来制作最小化的linux系统.所谓非模块化,就是将各种所需的硬件驱动.支持的文件系统等直接编译进内核,所以initramfs也就不需要了,对于网卡驱动,我们采用模块化编译,当然也可以根据自己网卡型号,直接将驱动编译进内核:最终在我们的mini linux上能通过DHCP自动获取ip并实现基于dropbear的远程终端登录. 实验环境: 操作系统:centos6.8(x86

第7章 进程关系(5)_贯穿案例2:mini shell(2)

5. 贯穿案例2:mini shell(2) (1)己经完成的功能:pwd.cd.exit命令 (2)阶段性目标: ①env.export.echo及其他命令 ②标准输入.输出重定向">"."<".">>" ③设置后台进程 [编程实验]mini  shell //job.h //job.c //mshell.c