📄 staker.m
字号:
updateMainFcn();
set(hMain,'Visible','on');
end
drawnow;
case 'FONT_NAME',
value = get(source,'String');
set(hFont,'FontName',value);
newPreferences.fontName = value;
drawnow;
case 'FONT_SIZE',
value = round(str2double(get(source,'String')));
if (isfinite(value) && (value > 0)),
set(source,'String',num2str(value));
set(hFont,'FontSize',value);
newPreferences.fontSize = value;
drawnow;
else
set(source,'String',num2str(newPreferences.fontSize));
bomb_error(hModal,'invalidValue','font size');
end
case 'HELP',
display_help(hModal);
case 'NUMERIC',
value = str2double(get(source,'String'));
fieldData = get(source,'UserData');
fieldName = fieldData{1};
if isnan(value),
set(source,'String',...
num2str(newPreferences.(fieldName),'%0.4f'));
switch fieldName,
case 'azimuthGain',
bomb_error(hModal,'invalidValue','azimuth gain');
case 'elevationGain',
bomb_error(hModal,'invalidValue','elevation gain');
case 'rotationGain',
bomb_error(hModal,'invalidValue','rotation gain');
case 'zoomGain',
bomb_error(hModal,'invalidValue','zoom gain');
case 'trajectoryStep',
bomb_error(hModal,'invalidValue','trajectory step');
case 'blastStep',
bomb_error(hModal,'invalidValue','blast step');
end
else
value = max(min(value,fieldData{3}),fieldData{2});
set(source,'String',num2str(value,'%0.4f'));
newPreferences.(fieldName) = value;
drawnow;
end
end
end
end
end
%------------------------------------------------------------------------
function generate_terrain
%
% Generates a game terrain.
%
%------------------------------------------------------------------------
if (isempty(mapX) || isempty(mapY)),
[mapX,mapY] = meshgrid(MAP_LIMIT.*linspace(-1,1,N_MAP));
end
if isempty(mapZ),
% Initialize terrain and environment variables:
if (locationIndex == 2),
locationIndex = round(rand*(length(LOCATION_LIST)-1))+1;
else
locationIndex = locationIndex-2;
end
mapGenerationState = rand('twister');
switch LOCATION_LIST{locationIndex},
case 'Highlands',
scale = [2000 4000 400]; % Height, expanse, and steepness, in ft
mapFill = 50*(MAP_LIMIT/(16000*N_MAP))^2;
index = find(rand(N_MAP) < mapFill); % Obstacle positions
nSolids = length(index);
solidObstacles = [index ones(nSolids,1)*scale];
nGhosts = 0;
ghostObstacles = [];
mapFilter = [];
mapNoise = 200; % ft
waterLevel = 1000; % ft
horizonFill = 0.07;
edgeColor = [0.45 0.45 0.5; 0.5 0.54 0.48];
locationValue = 1.5; % dollars per billion cubic ft
windSpeed = 30*normrand(1,-1,5)+30; % 0-180 mph
if useLocalTime,
timeOfDay = clock;
timeOfDay = timeOfDay(4:6);
else
timeOfDay = round([23 59 59].*rand(1,3));
end
end
windTheta = 2*pi*rand;
windVector = windSpeed.*[cos(windTheta) -sin(windTheta) 0];
% Generate terrain mesh:
mapZ = zeros(N_MAP);
for i = 1:nSolids,
index = solidObstacles(i,1);
temp = solidObstacles(i,2:4);
distance = sqrt((mapX-mapX(index)).^2+(mapY-mapY(index)).^2);
mapZ = mapZ+temp(1)./(1+exp((distance-temp(2))./temp(3)));
end
for i = 1:nGhosts,
index = ghostObstacles(i,1);
temp = ghostObstacles(i,2:4);
distance = sqrt((mapX-mapX(index)).^2+(mapY-mapY(index)).^2);
mapZ = max(mapZ,temp(1)./(1+exp((distance-temp(2))./temp(3))));
end
if (~isempty(mapFilter)),
mapZ = imfilter(mapZ,mapFilter,'replicate');
end
mapZ = mapZ+mapNoise.*rand(N_MAP);
if any(mapZ(:) > (MAX_HEIGHT+waterLevel)),
mapZ = mapZ.*((MAX_HEIGHT+waterLevel)/max(mapZ(:)));
end
if (waterLevel > 0),
isWater = true;
mapZ = mapZ-waterLevel;
end
mapZ(mapZ < MIN_HEIGHT) = MIN_HEIGHT;
% Generate horizon:
nHorizon = ceil(2*pi*HORIZON_LIMIT/MAP_DELTA);
horizonZ = zeros(1,nHorizon);
index = find(rand(1,nHorizon) < horizonFill);
for i = 1:length(index),
distance = MAP_DELTA.*abs((1:nHorizon)-index(i));
horizonZ = horizonZ+...
scale(1)./(1+exp((distance-scale(2))./scale(3)));
end
if (waterLevel > 0),
horizonZ = horizonZ-waterLevel;
end
horizonZ(horizonZ < 0) = 0;
temp = max(mapZ(:));
if any(horizonZ > temp),
horizonZ = horizonZ.*temp./max(horizonZ);
end
index = [1:10 (nHorizon-9):nHorizon];
temp = [linspace(0.5,1,10) linspace(1,0.5,10)];
horizonZ(index) = temp.*horizonZ(index)+...
(1-temp).*fliplr(horizonZ(index));
% Generate terrain texture map:
delta = (N_MAP-1)/(2*N_IMAGE);
index = (1+delta):(2*delta):(N_MAP-delta);
mapHeight = interp2(mapZ,index,index.');
if (waterLevel > 0),
waterLevel = 0;
nearWater = (imfilter(double(mapHeight < 0),fspecial('disk',10),...
'replicate') > 0);
else
mapHeight = mapHeight-waterLevel;
end
[mapGradientX,mapGradientY] = gradient(mapZ,MAP_DELTA);
mapGradient = sqrt(mapGradientX.^2+mapGradientY.^2);
notSteep = (interp2(mapGradient,index,index.') <= SLOPE_LIMIT);
switch LOCATION_LIST{locationIndex},
case 'Highlands',
terrainFile = fullfile(TEXTURE_PATH,'dirt.jpg');
mapC = double(reshape(imread(terrainFile),N_PIXELS,3));
index = ~notSteep;
add_terrain('stone',3);
index = (mapHeight > SNOW_LINE);
add_terrain('snow',10);
tempIndex = notSteep & (mapHeight < 50);
index = tempIndex & (~nearWater);
add_terrain('silt',3);
index = tempIndex & nearWater;
add_terrain('beach',3);
tempIndex = notSteep & (mapHeight > 50) & ...
(mapHeight < TREE_LINE);
index = tempIndex;
index(index) = (rand(sum(index(:)),1) > 0.996);
index = (imfilter(double(index),fspecial('disk',20),...
'replicate') > 0.001) & tempIndex;
add_terrain('grass',5);
index = tempIndex;
index(index) = (rand(sum(index(:)),1) > 0.999);
index = (imfilter(double(index),fspecial('disk',20),...
'replicate') > 0.001) & tempIndex;
add_terrain('forest',3);
end
mapC = reshape(uint8(mapC),N_IMAGE,N_IMAGE,3);
% Initialize staker positions and settings:
mapIndex = [2 floor((N_MAP-1)/2) ceil((N_MAP+1)/2)+1 N_MAP-1;...
ceil((N_MAP+1)/2)+1 N_MAP-1 2 floor((N_MAP-1)/2);...
2 floor((N_MAP-1)/2) 2 floor((N_MAP-1)/2);...
ceil((N_MAP+1)/2)+1 N_MAP-1 ceil((N_MAP+1)/2)+1 N_MAP-1];
muX = 0.625.*MAP_LIMIT.*[1 -1 -1 1];
muY = 0.625.*MAP_LIMIT.*[-1 1 -1 1];
sigma = 0.125*MAP_LIMIT^2;
for i = 1:nPlayers,
rIndex = mapIndex(i,1):mapIndex(i,2);
cIndex = mapIndex(i,3):mapIndex(i,4);
x = mapX(rIndex,cIndex);
y = mapY(rIndex,cIndex);
z = mapZ(rIndex,cIndex);
slope = mapGradient(rIndex,cIndex);
temp = exp(-((x-muX(i)).^2+(y-muY(i)).^2)./sigma).*...
rand(size(z)).*((z > 0) & (slope < SLOPE_LIMIT));
[temp,index] = max(temp(:));
players(i).position = [x(index) y(index) z(index)];
players(i).settings = [0 0 100 0];
players(i).camera = CAMERA_DEFAULT;
end
end
%----------------------------------------------------------------------
function add_terrain(terrainFile,radius)
%
% Add a terrain pattern to the texture map.
%
%----------------------------------------------------------------------
if any(index(:)),
terrainFile = fullfile(TEXTURE_PATH,[terrainFile,'.jpg']);
terrain = reshape(imread(terrainFile),N_PIXELS,3);
b = imfilter(double(index),fspecial('disk',radius),'replicate');
mask = (b(:) > 0);
b = b(mask)*ones(1,3);
mapC(mask,:) = (1-b).*mapC(mask,:)+b.*double(terrain(mask,:));
end
end
end
%------------------------------------------------------------------------
function initialize_game
%
% Initializes the game figure window and uicontrol interface.
%
%------------------------------------------------------------------------
% Initialize variables:
updateGameFcn = @update_game;
axesPosition = [1 126 600 410];
playerData = players(currentPlayer);
capacity = playerData.capacity;
settings = playerData.settings;
cameraProperties = {'CameraPosition','CameraTarget',...
'CameraUpVector','CameraViewAngle'};
cameraData = playerData.camera;
startMessage = 'Status -';
for i = 1:nPlayers,
startMessage = [startMessage ' ' players(i).name ' = ' ...
num2str(players(i).capacity,'%6.2f') '%'];
end
startTime = datestr(status.suspendedGames(currentGame).lastPlayed);
startMessage = {startMessage; ['Starting game - ',startTime]};
windSpeed = [num2str(sqrt(sum(windVector.^2)),'%10.2f'),' mph'];
windTheta = atan2(windVector(2),windVector(1))-pi/4;
windData = [cos(windTheta) -sin(windTheta); ...
sin(windTheta) cos(windTheta)]*...
[0 0.2 0.1 0.1 -0.1 -0.1 -0.2; ...
0.4 0.2 0.2 -0.4 -0.4 0.2 0.2];
blastC = imread(fullfile(TEXTURE_PATH,'fire.jpg'));
rubbleFile = fullfile(TEXTURE_PATH,'rubble.jpg');
rubbleC = double(reshape(imread(rubbleFile),N_PIXELS,3));
isActive = false;
selection = 'none';
cameraPoint = [];
targetPoint = [];
upVector = [];
viewAngle = [];
sightVector = [];
crossVector = [];
rotationVector = [];
currentTheta = [];
origin = [];
% Create game figure window:
hGame = make_figure([1+(SCREEN_SIZE(3:4)-[600 600])./2 600 600],...
'CloseRequestFcn',@callback_game,...
'Color',edgeColor(2,:),...
'Name',['Staker v',BOMB_VERSION],...
'Renderer','OpenGL','Resize','on',...
'ResizeFcn',@resize_game,'Tag','STAKER_GAME',...
'WindowButtonDownFcn',{@mouse_game;'down'},...
'WindowButtonMotionFcn',{@mouse_game;'standby'},...
'WindowButtonUpFcn',{@mouse_game;'up'});
% Create axes:
hMap = make_axes(hGame,axesPosition,cameraProperties,cameraData,...
'DataAspectRatio',[1 1 1],...
'PlotBoxAspectRatioMode','manual',...
'Projection','perspective',...
'XLim',MAP_LIMIT.*[-2 2],'YLim',MAP_LIMIT.*[-2 2],...
'ZLim',[MIN_HEIGHT 2*MAP_LIMIT]);
update_limits(cameraData{2}-cameraData{1});
% Plot terrain:
hTerrain = plot_surface(hMap,mapX,mapY,mapZ,mapC);
% Plot terrain edges:
nAngular = 4*N_MAP-3;
nRadial = 10;
theta = linspace(5*pi/4,-3*pi/4,nAngular).';
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -